зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b9a12d9376
Коммит
feac503206
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче