Bug 1179967 - Always rewrite links to absolute in nsWebBrowserPersist instead of side-effecting document. r=jst

--HG--
extra : commitid : JJTI70LvCnb
extra : rebase_source : 8a4b564e630a291e7866ba209a5f7dc4b1284a71
This commit is contained in:
Jed Davis 2015-07-15 12:15:48 -07:00
Родитель b9a12d9376
Коммит feac503206
2 изменённых файлов: 6 добавлений и 231 удалений

Просмотреть файл

@ -1674,9 +1674,6 @@ nsresult nsWebBrowserPersist::SaveDocumentInternal(
}
else
{
// Set the document base to ensure relative links still work
SetDocumentBase(aDocument, mCurrentBaseURI);
// Get the content type to save with
nsXPIDLString realContentType;
GetDocEncoderContentType(aDocument,
@ -1689,7 +1686,6 @@ nsresult nsWebBrowserPersist::SaveDocumentInternal(
// Save the document
rv = SaveDocumentWithFixup(
aDocument,
nullptr, // no dom fixup
aFile,
mReplaceExisting,
contentType,
@ -1728,11 +1724,6 @@ nsresult nsWebBrowserPersist::SaveDocuments()
// Save the document, fixing it up with the new URIs as we do
nsEncoderNodeFixup *nodeFixup;
nodeFixup = new nsEncoderNodeFixup;
if (nodeFixup)
nodeFixup->mWebBrowserPersist = this;
// Get the content type
nsXPIDLString realContentType;
GetDocEncoderContentType(docData->mDocument,
@ -1745,7 +1736,6 @@ nsresult nsWebBrowserPersist::SaveDocuments()
// Save the document, fixing up the links as it goes out
rv = SaveDocumentWithFixup(
docData->mDocument,
nodeFixup,
docData->mFile,
mReplaceExisting,
contentType,
@ -3674,12 +3664,15 @@ nsWebBrowserPersist::CreateChannelFromURI(nsIURI *aURI, nsIChannel **aChannel)
nsresult
nsWebBrowserPersist::SaveDocumentWithFixup(
nsIDOMDocument *aDocument, nsIDocumentEncoderNodeFixup *aNodeFixup,
nsIDOMDocument *aDocument,
nsIURI *aFile, bool aReplaceExisting, const nsACString &aFormatType,
const nsCString &aSaveCharset, uint32_t aFlags)
{
NS_ENSURE_ARG_POINTER(aFile);
nsRefPtr<nsEncoderNodeFixup> nodeFixup = new nsEncoderNodeFixup();
nodeFixup->mWebBrowserPersist = this;
nsresult rv = NS_OK;
nsCOMPtr<nsIFile> localFile;
GetLocalFileFromURI(aFile, getter_AddRefs(localFile));
@ -3718,7 +3711,7 @@ nsWebBrowserPersist::SaveDocumentWithFixup(
mTargetBaseURI = aFile;
// Set the node fixup callback
encoder->SetNodeFixup(aNodeFixup);
encoder->SetNodeFixup(nodeFixup);
if (mWrapColumn && (aFlags & ENCODE_FLAGS_WRAP))
encoder->SetWrapColumn(mWrapColumn);
@ -3810,223 +3803,6 @@ nsWebBrowserPersist::MakeAndStoreLocalFilenameInURIMap(
return NS_OK;
}
// Ordered so that typical documents work fastest.
// strlen("blockquote")==10
static const char kSpecialXHTMLTags[][11] = {
"body",
"head",
"img",
"script",
"a",
"area",
"link",
"input",
"frame",
"iframe",
"object",
"applet",
"form",
"blockquote",
"q",
"del",
"ins"
};
static bool IsSpecialXHTMLTag(nsIDOMNode *aNode)
{
nsAutoString tmp;
aNode->GetNamespaceURI(tmp);
if (!tmp.EqualsLiteral("http://www.w3.org/1999/xhtml"))
return false;
aNode->GetLocalName(tmp);
for (uint32_t i = 0; i < ArrayLength(kSpecialXHTMLTags); i++) {
if (tmp.EqualsASCII(kSpecialXHTMLTags[i]))
{
// 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 true;
}
}
return false;
}
static bool HasSpecialXHTMLTags(nsIDOMNode *aParent)
{
if (IsSpecialXHTMLTag(aParent))
return true;
nsCOMPtr<nsIDOMNodeList> list;
aParent->GetChildNodes(getter_AddRefs(list));
if (list)
{
uint32_t count;
list->GetLength(&count);
uint32_t i;
for (i = 0; i < count; i++) {
nsCOMPtr<nsIDOMNode> node;
list->Item(i, getter_AddRefs(node));
if (!node)
break;
uint16_t nodeType;
node->GetNodeType(&nodeType);
if (nodeType == nsIDOMNode::ELEMENT_NODE) {
return HasSpecialXHTMLTags(node);
}
}
}
return false;
}
static bool NeedXHTMLBaseTag(nsIDOMDocument *aDocument)
{
nsCOMPtr<nsIDOMElement> docElement;
aDocument->GetDocumentElement(getter_AddRefs(docElement));
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(docElement));
if (node)
{
return HasSpecialXHTMLTags(node);
}
return false;
}
// Set document base. This could create an invalid XML document (still well-formed).
nsresult
nsWebBrowserPersist::SetDocumentBase(
nsIDOMDocument *aDocument, nsIURI *aBaseURI)
{
if (mPersistFlags & PERSIST_FLAGS_NO_BASE_TAG_MODIFICATIONS)
{
return NS_OK;
}
NS_ENSURE_ARG_POINTER(aBaseURI);
nsCOMPtr<nsIDOMXMLDocument> xmlDoc;
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(aDocument);
if (!htmlDoc)
{
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;
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;
headList->Item(0, getter_AddRefs(headNode));
headElement = do_QueryInterface(headNode);
}
if (!headElement)
{
// Create head and insert as first element
nsCOMPtr<nsIDOMNode> firstChildNode;
nsCOMPtr<nsIDOMNode> 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)
{
return NS_ERROR_FAILURE;
}
// Find or create the BASE element
NS_NAMED_LITERAL_STRING(kBase, "base");
nsCOMPtr<nsIDOMElement> baseElement;
nsCOMPtr<nsIDOMHTMLCollection> baseList;
if (xmlDoc)
{
headElement->GetElementsByTagNameNS(
kXHTMLNS,
kBase, getter_AddRefs(baseList));
}
else
{
headElement->GetElementsByTagName(
kBase, getter_AddRefs(baseList));
}
if (baseList)
{
nsCOMPtr<nsIDOMNode> baseNode;
baseList->Item(0, getter_AddRefs(baseNode));
baseElement = do_QueryInterface(baseNode);
}
// Add the BASE element
if (!baseElement)
{
nsCOMPtr<nsIDOMNode> newNode;
if (xmlDoc)
{
aDocument->CreateElementNS(
kXHTMLNS,
kBase, getter_AddRefs(baseElement));
}
else
{
aDocument->CreateElement(
kBase, getter_AddRefs(baseElement));
}
headElement->AppendChild(baseElement, getter_AddRefs(newNode));
}
if (!baseElement)
{
return NS_ERROR_FAILURE;
}
nsAutoCString uriSpec;
aBaseURI->GetSpec(uriSpec);
NS_ConvertUTF8toUTF16 href(uriSpec);
baseElement->SetAttribute(NS_LITERAL_STRING("href"), href);
return NS_OK;
}
// Decide if we need to apply conversion to the passed channel.
void nsWebBrowserPersist::SetApplyConversionIfNeeded(nsIChannel *aChannel)
{

Просмотреть файл

@ -138,12 +138,11 @@ private:
nsresult StoreAndFixupStyleSheet(nsIStyleSheet *aStyleSheet);
nsresult SaveDocumentWithFixup(
nsIDOMDocument *pDocument, nsIDocumentEncoderNodeFixup *pFixup,
nsIDOMDocument *pDocument,
nsIURI *aFile, bool aReplaceExisting, const nsACString &aFormatType,
const nsCString &aSaveCharset, uint32_t aFlags);
nsresult SaveSubframeContent(
nsIDOMDocument *aFrameContent, URIData *aData);
nsresult SetDocumentBase(nsIDOMDocument *aDocument, nsIURI *aBaseURI);
nsresult SendErrorStatusChange(
bool aIsReadError, nsresult aResult, nsIRequest *aRequest, nsIURI *aURI);
nsresult OnWalkDOMNode(nsIDOMNode *aNode);