Bug 146062 and bug 136718, pay attention to namespaces in XML documents, and fix the small but important logic/typo error in handling xml-stylesheet href pseudo-attribute. r=adamlock, sr=alecf.

git-svn-id: svn://10.0.0.236/trunk@134211 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
heikki%netscape.com 2002-11-20 23:09:00 +00:00
parent fbc6f0ced5
commit cdcb47665c
2 changed files with 175 additions and 35 deletions

View File

@ -50,6 +50,7 @@
#include "nsIFileURL.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMXMLDocument.h"
#include "nsIDOMDocumentTraversal.h"
#include "nsIDOMTreeWalker.h"
#include "nsIDOMNode.h"
@ -2240,7 +2241,7 @@ nsWebBrowserPersist::GetQuotedAttributeValue(
return PR_FALSE;
}
nsresult nsWebBrowserPersist::FixupXMLStyleSheetLink(nsIDOMProcessingInstruction *aPI, nsAString &aHref)
nsresult nsWebBrowserPersist::FixupXMLStyleSheetLink(nsIDOMProcessingInstruction *aPI, const nsAString &aHref)
{
NS_ENSURE_ARG_POINTER(aPI);
nsresult rv = NS_OK;
@ -2250,28 +2251,26 @@ nsresult nsWebBrowserPersist::FixupXMLStyleSheetLink(nsIDOMProcessingInstruction
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsAutoString href;
nsAutoString alternate;
nsAutoString charset;
nsAutoString title;
nsAutoString type;
nsAutoString media;
GetQuotedAttributeValue(data, NS_LITERAL_STRING("href"), href);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("alternate"), alternate);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("charset"), charset);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("title"), title);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("type"), type);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("media"), media);
// Construct and set a new data value for the xml-stylesheet
if (!aHref.IsEmpty())
if (!aHref.IsEmpty() && !href.IsEmpty())
{
nsAutoString alternate;
nsAutoString charset;
nsAutoString title;
nsAutoString type;
nsAutoString media;
GetQuotedAttributeValue(data, NS_LITERAL_STRING("alternate"), alternate);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("charset"), charset);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("title"), title);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("type"), type);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("media"), media);
NS_NAMED_LITERAL_STRING(kCloseAttr, "\" ");
nsAutoString newData;
if (!aHref.IsEmpty())
{
newData += NS_LITERAL_STRING("href=\"") + href + kCloseAttr;
}
newData += NS_LITERAL_STRING("href=\"") + aHref + kCloseAttr;
if (!title.IsEmpty())
{
newData += NS_LITERAL_STRING("title=\"") + title + kCloseAttr;
@ -2292,15 +2291,10 @@ nsresult nsWebBrowserPersist::FixupXMLStyleSheetLink(nsIDOMProcessingInstruction
{
newData += NS_LITERAL_STRING("alternate=\"") + alternate + kCloseAttr;
}
if (newData.Length() > 0)
{
newData.Truncate(newData.Length() - 1); // Remove the extra space on the end.
}
newData.Truncate(newData.Length() - 1); // Remove the extra space on the end.
aPI->SetData(newData);
}
aHref = href;
return rv;
}
@ -3133,7 +3127,98 @@ nsWebBrowserPersist::MakeAndStoreLocalFilenameInURIMap(
return NS_OK;
}
struct SpecialXHTMLTags {
PRUnichar name[sizeof(PRUnichar)*11]; // strlen("blockquote")==10
};
static PRBool IsSpecialXHTMLTag(nsIDOMNode *aNode)
{
nsAutoString ns;
aNode->GetNamespaceURI(ns);
if (!ns.Equals(NS_LITERAL_STRING("http://www.w3.org/1999/xhtml")))
return PR_FALSE;
// Ordered so that typical documents work fastest
static SpecialXHTMLTags tags[] = {
{'b','o','d','y',0},
{'h','e','a','d',0},
{'i','m','g',0},
{'s','c','r','i','p','t',0},
{'a',0},
{'a','r','e','a',0},
{'l','i','n','k',0},
{'i','n','p','u','t',0},
{'f','r','a','m','e',0},
{'i','f','r','a','m','e',0},
{'o','b','j','e','c','t',0},
{'a','p','p','l','e','t',0},
{'f','o','r','m',0},
{'b','l','o','c','k','q','u','o','t','e',0},
{'q',0},
{'d','e','l',0},
{'i','n','s',0},
{0}};
nsAutoString localName;
aNode->GetLocalName(localName);
PRInt32 i;
for (i = 0; tags[i].name[0]; i++) {
if (localName.Equals(tags[i].name))
{
// XXX This element MAY have URI attributes, but
// we are not actually checking if they are present.
// That would slow us down further, and I am not so sure
// how important that would be.
return PR_TRUE;
}
}
return PR_FALSE;
}
static PRBool HasSpecialXHTMLTags(nsIDOMNode *aParent)
{
if (IsSpecialXHTMLTag(aParent))
return PR_TRUE;
nsCOMPtr<nsIDOMNodeList> list;
aParent->GetChildNodes(getter_AddRefs(list));
if (list)
{
PRUint32 count;
list->GetLength(&count);
PRUint32 i;
for (i = 0; i < count; i++) {
nsCOMPtr<nsIDOMNode> node;
list->Item(i, getter_AddRefs(node));
if (!node)
break;
PRUint16 nodeType;
node->GetNodeType(&nodeType);
if (nodeType == nsIDOMNode::ELEMENT_NODE) {
return HasSpecialXHTMLTags(node);
}
}
}
return PR_FALSE;
}
static PRBool NeedXHTMLBaseTag(nsIDOMDocument *aDocument)
{
nsCOMPtr<nsIDOMElement> docElement;
aDocument->GetDocumentElement(getter_AddRefs(docElement));
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(docElement));
if (node)
{
return HasSpecialXHTMLTags(node);
}
return PR_FALSE;
}
// Set document base. This could create an invalid XML document (still well-formed).
nsresult
nsWebBrowserPersist::SetDocumentBase(
nsIDOMDocument *aDocument, nsIURI *aBaseURI)
@ -3143,17 +3228,39 @@ nsWebBrowserPersist::SetDocumentBase(
return NS_OK;
}
nsCOMPtr<nsIDOMXMLDocument> xmlDoc;
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(aDocument);
if (!htmlDoc)
{
return NS_ERROR_FAILURE;
xmlDoc = do_QueryInterface(aDocument);
if (!xmlDoc)
{
return NS_ERROR_FAILURE;
}
}
NS_NAMED_LITERAL_STRING(kXHTMLNS, "http://www.w3.org/1999/xhtml");
NS_NAMED_LITERAL_STRING(kHead, "head");
// Find the head element
nsCOMPtr<nsIDOMElement> headElement;
nsCOMPtr<nsIDOMNodeList> headList;
aDocument->GetElementsByTagName(
NS_LITERAL_STRING("head"), getter_AddRefs(headList));
if (xmlDoc)
{
// First see if there is XHTML content that needs base
// tags.
if (!NeedXHTMLBaseTag(aDocument))
return NS_OK;
aDocument->GetElementsByTagNameNS(
kXHTMLNS,
kHead, getter_AddRefs(headList));
}
else
{
aDocument->GetElementsByTagName(
kHead, getter_AddRefs(headList));
}
if (headList)
{
nsCOMPtr<nsIDOMNode> headNode;
@ -3165,10 +3272,24 @@ nsWebBrowserPersist::SetDocumentBase(
// Create head and insert as first element
nsCOMPtr<nsIDOMNode> firstChildNode;
nsCOMPtr<nsIDOMNode> newNode;
aDocument->CreateElement(
NS_LITERAL_STRING("head"), getter_AddRefs(headElement));
aDocument->GetFirstChild(getter_AddRefs(firstChildNode));
aDocument->InsertBefore(headElement, firstChildNode, getter_AddRefs(newNode));
if (xmlDoc)
{
aDocument->CreateElementNS(
kXHTMLNS,
kHead, getter_AddRefs(headElement));
}
else
{
aDocument->CreateElement(
kHead, getter_AddRefs(headElement));
}
nsCOMPtr<nsIDOMElement> documentElement;
aDocument->GetDocumentElement(getter_AddRefs(documentElement));
if (documentElement)
{
documentElement->GetFirstChild(getter_AddRefs(firstChildNode));
documentElement->InsertBefore(headElement, firstChildNode, getter_AddRefs(newNode));
}
}
if (!headElement)
{
@ -3176,10 +3297,20 @@ nsWebBrowserPersist::SetDocumentBase(
}
// Find or create the BASE element
NS_NAMED_LITERAL_STRING(kBase, "base");
nsCOMPtr<nsIDOMElement> baseElement;
nsCOMPtr<nsIDOMNodeList> baseList;
headElement->GetElementsByTagName(
NS_LITERAL_STRING("base"), getter_AddRefs(baseList));
if (xmlDoc)
{
headElement->GetElementsByTagNameNS(
kXHTMLNS,
kBase, getter_AddRefs(baseList));
}
else
{
headElement->GetElementsByTagName(
kBase, getter_AddRefs(baseList));
}
if (baseList)
{
nsCOMPtr<nsIDOMNode> baseNode;
@ -3193,8 +3324,17 @@ nsWebBrowserPersist::SetDocumentBase(
if (!baseElement)
{
nsCOMPtr<nsIDOMNode> newNode;
aDocument->CreateElement(
NS_LITERAL_STRING("base"), getter_AddRefs(baseElement));
if (xmlDoc)
{
aDocument->CreateElementNS(
kXHTMLNS,
kBase, getter_AddRefs(baseElement));
}
else
{
aDocument->CreateElement(
kBase, getter_AddRefs(baseElement));
}
headElement->AppendChild(baseElement, getter_AddRefs(newNode));
}
if (!baseElement)

View File

@ -122,7 +122,7 @@ private:
nsresult FixupURI(nsAString &aURI);
nsresult FixupNodeAttribute(nsIDOMNode *aNode, const char *aAttribute);
nsresult FixupAnchor(nsIDOMNode *aNode);
nsresult FixupXMLStyleSheetLink(nsIDOMProcessingInstruction *aPI, nsAString &aHref);
nsresult FixupXMLStyleSheetLink(nsIDOMProcessingInstruction *aPI, const nsAString &aHref);
nsresult GetXMLStyleSheetLink(nsIDOMProcessingInstruction *aPI, nsAString &aHref);
nsresult StoreAndFixupStyleSheet(nsIStyleSheet *aStyleSheet);