mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 515401: Make implementation of <base> HTML5 compliant, and clean it up. r=benjamn a=dholbert
This commit is contained in:
parent
70a324e5f9
commit
24b255ef47
@ -115,8 +115,8 @@ class Link;
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x17e1c0ce, 0x3883, 0x4efc, \
|
||||
{ 0xbf, 0xdf, 0x40, 0xa6, 0x26, 0x9f, 0xbd, 0x2c } }
|
||||
{ 0x4a0c9bfa, 0xef60, 0x4bb2, \
|
||||
{ 0x87, 0x5e, 0xac, 0xdb, 0xe8, 0xfe, 0xa1, 0xb5 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
@ -249,8 +249,7 @@ public:
|
||||
/**
|
||||
* Get/Set the base target of a link in a document.
|
||||
*/
|
||||
virtual void GetBaseTarget(nsAString &aBaseTarget) const = 0;
|
||||
virtual void SetBaseTarget(const nsAString &aBaseTarget) = 0;
|
||||
virtual void GetBaseTarget(nsAString &aBaseTarget) = 0;
|
||||
|
||||
/**
|
||||
* Return a standard name for the document's character set.
|
||||
@ -1328,24 +1327,6 @@ public:
|
||||
*/
|
||||
virtual PRInt32 GetDocumentState() = 0;
|
||||
|
||||
/**
|
||||
* Gets the document's cached pointer to the first <base> element in this
|
||||
* document which has an href attribute. If the document doesn't contain any
|
||||
* <base> elements with an href, returns null.
|
||||
*/
|
||||
virtual nsIContent* GetFirstBaseNodeWithHref() = 0;
|
||||
|
||||
/**
|
||||
* Sets the document's cached pointer to the first <base> element with an
|
||||
* href attribute in this document and updates the document's base URI
|
||||
* according to the element's href.
|
||||
*
|
||||
* If the given node is the same as the current first base node, this
|
||||
* function still updates the document's base URI according to the node's
|
||||
* href, if it changed.
|
||||
*/
|
||||
virtual nsresult SetFirstBaseNodeWithHref(nsIContent *node) = 0;
|
||||
|
||||
virtual nsISupports* GetCurrentContentSink() = 0;
|
||||
|
||||
/**
|
||||
|
@ -232,7 +232,6 @@ nsContentSink::Init(nsIDocument* aDoc,
|
||||
mDocument = aDoc;
|
||||
|
||||
mDocumentURI = aURI;
|
||||
mDocumentBaseURI = aURI;
|
||||
mDocShell = do_QueryInterface(aContainer);
|
||||
if (mDocShell) {
|
||||
PRUint32 loadType = 0;
|
||||
@ -781,7 +780,8 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> url;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(url), aHref, nsnull, mDocumentBaseURI);
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(url), aHref, nsnull,
|
||||
mDocument->GetBaseURI());
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// The URI is bad, move along, don't propagate the error (for now)
|
||||
@ -890,7 +890,7 @@ nsContentSink::PrefetchHref(const nsAString &aHref,
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), aHref,
|
||||
charset.IsEmpty() ? nsnull : PromiseFlatCString(charset).get(),
|
||||
mDocumentBaseURI);
|
||||
mDocument->GetBaseURI());
|
||||
if (uri) {
|
||||
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aSource);
|
||||
prefetchService->PrefetchURI(uri, mDocumentURI, domNode, aExplicit);
|
||||
|
@ -306,7 +306,6 @@ protected:
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsIParser> mParser;
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
nsCOMPtr<nsIURI> mDocumentBaseURI;
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
nsRefPtr<mozilla::css::Loader> mCSSLoader;
|
||||
nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
|
||||
|
@ -2913,48 +2913,45 @@ nsDocument::ReleaseCapture()
|
||||
nsresult
|
||||
nsDocument::SetBaseURI(nsIURI* aURI)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIURI> oldBase = nsIDocument::GetBaseURI();
|
||||
if (aURI) {
|
||||
rv = nsContentUtils::GetSecurityManager()->
|
||||
CheckLoadURIWithPrincipal(NodePrincipal(), aURI,
|
||||
nsIScriptSecurityManager::STANDARD);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mDocumentBaseURI = NS_TryToMakeImmutable(aURI);
|
||||
if (!aURI && !mDocumentBaseURI) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Don't do anything if the URI wasn't actually changed.
|
||||
if (aURI && mDocumentBaseURI) {
|
||||
PRBool equalBases = PR_FALSE;
|
||||
mDocumentBaseURI->Equals(aURI, &equalBases);
|
||||
if (equalBases) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (aURI) {
|
||||
mDocumentBaseURI = NS_TryToMakeImmutable(aURI);
|
||||
} else {
|
||||
mDocumentBaseURI = nsnull;
|
||||
}
|
||||
RefreshLinkHrefs();
|
||||
|
||||
nsIURI* newBase = nsIDocument::GetBaseURI();
|
||||
PRBool equalBases = PR_FALSE;
|
||||
if (oldBase && newBase) {
|
||||
oldBase->Equals(newBase, &equalBases);
|
||||
}
|
||||
else {
|
||||
equalBases = !oldBase && !newBase;
|
||||
}
|
||||
|
||||
// If the document's base URI has changed, we need to re-resolve all the
|
||||
// cached link hrefs relative to the new base.
|
||||
if (!equalBases) {
|
||||
RefreshLinkHrefs();
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::GetBaseTarget(nsAString &aBaseTarget) const
|
||||
nsDocument::GetBaseTarget(nsAString &aBaseTarget)
|
||||
{
|
||||
aBaseTarget.Assign(mBaseTarget);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::SetBaseTarget(const nsAString &aBaseTarget)
|
||||
{
|
||||
mBaseTarget.Assign(aBaseTarget);
|
||||
aBaseTarget.Truncate();
|
||||
nsIContent* head = GetHeadContent();
|
||||
if (!head) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ChildIterator iter(head); !iter.IsDone(); iter.Next()) {
|
||||
nsIContent* child = iter;
|
||||
if (child->NodeInfo()->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
child->GetAttr(kNameSpaceID_None, nsGkAtoms::target, aBaseTarget)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -7572,48 +7569,6 @@ nsDocument::RefreshLinkHrefs()
|
||||
}
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsDocument::GetFirstBaseNodeWithHref()
|
||||
{
|
||||
return mFirstBaseNodeWithHref;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::SetFirstBaseNodeWithHref(nsIContent *elem)
|
||||
{
|
||||
mFirstBaseNodeWithHref = elem;
|
||||
|
||||
if (!elem) {
|
||||
SetBaseURI(nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(elem->Tag() == nsGkAtoms::base,
|
||||
"Setting base node to a non <base> element?");
|
||||
NS_ASSERTION(elem->GetNameSpaceID() == kNameSpaceID_XHTML,
|
||||
"Setting base node to a non XHTML element?");
|
||||
|
||||
nsIDocument* doc = elem->GetOwnerDoc();
|
||||
nsIURI* currentURI = nsIDocument::GetDocumentURI();
|
||||
|
||||
// Resolve the <base> element's href relative to our current URI
|
||||
nsAutoString href;
|
||||
PRBool hasHref = elem->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
|
||||
NS_ASSERTION(hasHref,
|
||||
"Setting first base node to a node with no href attr?");
|
||||
|
||||
nsCOMPtr<nsIURI> newBaseURI;
|
||||
nsContentUtils::NewURIWithDocumentCharset(
|
||||
getter_AddRefs(newBaseURI), href, doc, currentURI);
|
||||
|
||||
// Try to set our base URI. If that fails, try to set our base URI to null.
|
||||
nsresult rv = SetBaseURI(newBaseURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
return SetBaseURI(nsnull);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetScriptTypeID(PRUint32 *aScriptType)
|
||||
{
|
||||
|
@ -544,8 +544,7 @@ public:
|
||||
/**
|
||||
* Get/Set the base target of a link in a document.
|
||||
*/
|
||||
virtual void GetBaseTarget(nsAString &aBaseTarget) const;
|
||||
virtual void SetBaseTarget(const nsAString &aBaseTarget);
|
||||
virtual void GetBaseTarget(nsAString &aBaseTarget);
|
||||
|
||||
/**
|
||||
* Return a standard name for the document's character set. This will
|
||||
|
@ -423,8 +423,6 @@ GK_ATOM(href, "href")
|
||||
GK_ATOM(hreflang, "hreflang")
|
||||
GK_ATOM(hspace, "hspace")
|
||||
GK_ATOM(html, "html")
|
||||
GK_ATOM(htmlBaseHref, "html-base-href")
|
||||
GK_ATOM(htmlBaseTarget, "html-base-target")
|
||||
GK_ATOM(httpEquiv, "http-equiv")
|
||||
GK_ATOM(i, "i")
|
||||
GK_ATOM(id, "id")
|
||||
|
@ -366,6 +366,7 @@ _TEST_FILES = test_bug5141.html \
|
||||
test_bug545644.html \
|
||||
test_bug545644.xhtml \
|
||||
test_bug553896.xhtml \
|
||||
test_bug515401.html \
|
||||
test_bug541937.html \
|
||||
file_bug541937.html \
|
||||
file_bug541937.xhtml \
|
||||
|
134
content/base/test/test_bug515401.html
Normal file
134
content/base/test/test_bug515401.html
Normal file
@ -0,0 +1,134 @@
|
||||
<<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=515401
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 515401</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<base id=basehref href="base/">
|
||||
<base id=basehref2>
|
||||
<base id=basetarget target="def_target">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=515401">Mozilla Bug 515401</a>
|
||||
<a id=a href="dest.html">Simple link</a>
|
||||
<a id=awtarget target="a_target">Link with target</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var a = $('a');
|
||||
var awtarget = $('awtarget');
|
||||
var head = document.documentElement.firstElementChild;
|
||||
|
||||
// Test targets
|
||||
is(a.target, "def_target", "using default target");
|
||||
is(awtarget.target, "a_target", "specified target");
|
||||
$('basetarget').setAttribute("target", "new_def_target");
|
||||
is(a.target, "new_def_target", "using new default target");
|
||||
is(awtarget.target, "a_target", "still specified target");
|
||||
$('basetarget').removeAttribute("target");
|
||||
is(a.target, "", "no target");
|
||||
is(awtarget.target, "a_target", "yet still specified target");
|
||||
newbasetarget = document.createElement('base');
|
||||
newbasetarget.target = "new_target_elem";
|
||||
head.appendChild(newbasetarget);
|
||||
is(a.target, "new_target_elem", "new target element");
|
||||
is(awtarget.target, "a_target", "yet still specified target");
|
||||
newbasetarget.target = "new_target_elem_value";
|
||||
is(a.target, "new_target_elem_value", "new target element attribute");
|
||||
is(awtarget.target, "a_target", "yet still specified target");
|
||||
newbasetarget.target = "";
|
||||
is(a.target, "", "new target element no attribute");
|
||||
is(awtarget.target, "a_target", "yet still specified target");
|
||||
|
||||
|
||||
// link hrefs
|
||||
var basehref = $('basehref');
|
||||
var basehref2 = $('basehref2');
|
||||
var pre = "http://mochi.test:8888/tests/content/base/test/";
|
||||
function verifyBase(base, test) {
|
||||
if (base == "") {
|
||||
is(document.baseURI, document.URL, "document base when " + test);
|
||||
is(a.href, pre + "dest.html", "link href when " + test);
|
||||
}
|
||||
else {
|
||||
is(document.baseURI, pre + base, "document base when " + test);
|
||||
is(a.href, pre + base + "dest.html", "link href when " + test);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// In document base
|
||||
verifyBase("base/", "from markup");
|
||||
|
||||
// Modify existing <base>
|
||||
basehref.href = "base2/";
|
||||
verifyBase("base2/", "modify existing");
|
||||
|
||||
// Remove href on existing element
|
||||
basehref.removeAttribute("href");
|
||||
verifyBase("", "remove href on existing element");
|
||||
|
||||
// Create href on existing element
|
||||
basehref.href = "base3/";
|
||||
verifyBase("base3/", "create href on existing element");
|
||||
|
||||
// Fall back to second after remove attr
|
||||
basehref2.href = "base4/";
|
||||
verifyBase("base3/", "add href on second base");
|
||||
basehref.removeAttribute("href");
|
||||
verifyBase("base4/", "fall back to second after remove attr");
|
||||
|
||||
// Set href on existing again
|
||||
basehref.href = "base5/";
|
||||
verifyBase("base5/", "set href on existing again");
|
||||
|
||||
// Unset href on second
|
||||
basehref2.removeAttribute("href");
|
||||
verifyBase("base5/", "unset href on second");
|
||||
|
||||
// Insert base with href before existing
|
||||
var basehref0 = document.createElement("base");
|
||||
basehref0.href = "base6/";
|
||||
verifyBase("base5/", "nothing modified");
|
||||
head.insertBefore(basehref0, head.firstChild.nextElementSibling);
|
||||
verifyBase("base6/", "insert base with href before existing");
|
||||
|
||||
// Insert base as grandchild of head
|
||||
var baseerr = document.createElement("base");
|
||||
baseerr.href = "baseerr/";
|
||||
var tmp = document.createElement("head");
|
||||
tmp.appendChild(baseerr);
|
||||
head.insertBefore(tmp, head.firstChild);
|
||||
verifyBase("base6/", "inserted base as grandchild of head");
|
||||
is(baseerr.parentNode.parentNode, head, "base got inserted correctly");
|
||||
|
||||
// Remove secondary bases
|
||||
var tmp, tmp2;
|
||||
for (tmp = head.firstChild; tmp = tmp.nextSibling; tmp) {
|
||||
if (tmp.localName == "base" && tmp != basehref0) {
|
||||
tmp2 = tmp.previousSibling;
|
||||
head.removeChild(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
verifyBase("base6/", "remove unneeded base");
|
||||
}
|
||||
|
||||
// Remove head
|
||||
document.documentElement.removeChild(head);
|
||||
verifyBase("", "removed head");
|
||||
|
||||
// Insert base in body
|
||||
document.body.insertBefore(baseerr, document.body.firstChild);
|
||||
verifyBase("", "inserted base in body");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -266,23 +266,6 @@ nsGenericHTMLElement::CopyInnerTo(nsGenericElement* aDst) const
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Copy the baseuri and basetarget
|
||||
void* prop;
|
||||
if ((prop = GetProperty(nsGkAtoms::htmlBaseHref))) {
|
||||
rv = aDst->SetProperty(nsGkAtoms::htmlBaseHref, prop,
|
||||
nsPropertyTable::SupportsDtorFunc, PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ADDREF(static_cast<nsIURI*>(prop));
|
||||
}
|
||||
}
|
||||
if ((prop = GetProperty(nsGkAtoms::htmlBaseTarget))) {
|
||||
rv = aDst->SetProperty(nsGkAtoms::htmlBaseTarget, prop,
|
||||
nsPropertyTable::SupportsDtorFunc, PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ADDREF(static_cast<nsIAtom*>(prop));
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1153,30 +1136,9 @@ nsGenericHTMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI>
|
||||
nsGenericHTMLElement::GetBaseURI() const
|
||||
{
|
||||
void* prop;
|
||||
if (HasFlag(NODE_HAS_PROPERTIES) && (prop = GetProperty(nsGkAtoms::htmlBaseHref))) {
|
||||
nsIURI* uri = static_cast<nsIURI*>(prop);
|
||||
NS_ADDREF(uri);
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
return nsGenericHTMLElementBase::GetBaseURI();
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::GetBaseTarget(nsAString& aBaseTarget) const
|
||||
{
|
||||
void* prop;
|
||||
if (HasFlag(NODE_HAS_PROPERTIES) && (prop = GetProperty(nsGkAtoms::htmlBaseTarget))) {
|
||||
static_cast<nsIAtom*>(prop)->ToString(aBaseTarget);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nsIDocument* ownerDoc = GetOwnerDoc();
|
||||
if (ownerDoc) {
|
||||
ownerDoc->GetBaseTarget(aBaseTarget);
|
||||
|
@ -209,8 +209,6 @@ public:
|
||||
|
||||
virtual void UpdateEditableState();
|
||||
|
||||
already_AddRefed<nsIURI> GetBaseURI() const;
|
||||
|
||||
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
|
@ -428,6 +428,43 @@ nsHTMLSharedElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
||||
return nsGenericHTMLElement::IsAttributeMapped(aAttribute);
|
||||
}
|
||||
|
||||
void
|
||||
SetBaseURIUsingFirstBaseWithHref(nsIContent* aHead, nsIContent* aMustMatch)
|
||||
{
|
||||
NS_PRECONDITION(aHead && aHead->GetOwnerDoc() &&
|
||||
aHead->GetOwnerDoc()->GetHeadContent() == aHead,
|
||||
"Bad head");
|
||||
|
||||
nsIDocument* doc = aHead->GetOwnerDoc();
|
||||
|
||||
for (nsINode::ChildIterator iter(aHead); !iter.IsDone(); iter.Next()) {
|
||||
nsIContent* child = iter;
|
||||
if (child->NodeInfo()->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
child->HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
|
||||
if (aMustMatch && child != aMustMatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Resolve the <base> element's href relative to our document URI
|
||||
nsAutoString href;
|
||||
child->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
|
||||
|
||||
nsCOMPtr<nsIURI> newBaseURI;
|
||||
nsContentUtils::NewURIWithDocumentCharset(
|
||||
getter_AddRefs(newBaseURI), href, doc, doc->GetDocumentURI());
|
||||
|
||||
// Try to set our base URI. If that fails, try to set base URI to null
|
||||
nsresult rv = doc->SetBaseURI(newBaseURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
doc->SetBaseURI(nsnull);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
doc->SetBaseURI(nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLSharedElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
@ -435,64 +472,22 @@ nsHTMLSharedElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If the href attribute of a <base> tag is changing, we may need to update
|
||||
// the document's base URI, which will cause all the links on the page to be
|
||||
// re-resolved given the new base.
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
nsIContent* head;
|
||||
if (mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
aName == nsGkAtoms::href &&
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
GetOwnerDoc() == GetCurrentDoc()) {
|
||||
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
NS_ENSURE_TRUE(doc, NS_OK);
|
||||
|
||||
// We become the first base node with an href if
|
||||
// * there's no other base node with an href, or
|
||||
// * we come before the first base node with an href (this would happen
|
||||
// if we didn't have an href before this call to SetAttr).
|
||||
// Additionally, we call doc->SetFirstBaseNodeWithHref if we're the first
|
||||
// base node with an href so the document updates its base URI with our new
|
||||
// href.
|
||||
nsIContent* firstBase = doc->GetFirstBaseNodeWithHref();
|
||||
if (!firstBase || this == firstBase ||
|
||||
nsContentUtils::PositionIsBefore(this, firstBase)) {
|
||||
|
||||
return doc->SetFirstBaseNodeWithHref(this);
|
||||
}
|
||||
IsInDoc() &&
|
||||
(head = GetParent()) &&
|
||||
head == GetOwnerDoc()->GetHeadContent()) {
|
||||
SetBaseURIUsingFirstBaseWithHref(head, this);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Helper function for nsHTMLSharedElement::UnbindFromTree. Finds and returns
|
||||
// the first <base> tag with an href attribute which is a child of elem, if one
|
||||
// exists.
|
||||
static nsIContent*
|
||||
FindBaseRecursive(nsINode * const elem)
|
||||
{
|
||||
// We can't use NS_GetContentList to get the list of <base> elements, because
|
||||
// that flushes content notifications, and we need this function to work in
|
||||
// UnbindFromTree. Once we land the HTML5 parser and get rid of content
|
||||
// notifications, we should fix this up. (bug 515819)
|
||||
|
||||
PRUint32 childCount;
|
||||
nsIContent * const * child = elem->GetChildArray(&childCount);
|
||||
nsIContent * const * end = child + childCount;
|
||||
for ( ; child != end; child++) {
|
||||
nsIContent *childElem = *child;
|
||||
|
||||
if (childElem->NodeInfo()->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
childElem->HasAttr(kNameSpaceID_None, nsGkAtoms::href))
|
||||
return childElem;
|
||||
|
||||
nsIContent* base = FindBaseRecursive(childElem);
|
||||
if (base)
|
||||
return base;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -500,31 +495,22 @@ nsHTMLSharedElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aName, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If we're the first <base> with an href and our href attribute is being
|
||||
// unset, then we're no longer the first <base> with an href, and we need to
|
||||
// find the new one.
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
nsIContent* head;
|
||||
if (mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
aName == nsGkAtoms::href &&
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
GetOwnerDoc() == GetCurrentDoc()) {
|
||||
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
NS_ENSURE_TRUE(doc, NS_OK);
|
||||
|
||||
// If we're not the first <base> in the document, then unsetting our href
|
||||
// doesn't affect the document's base URI.
|
||||
if (this != doc->GetFirstBaseNodeWithHref())
|
||||
return NS_OK;
|
||||
|
||||
// We're the first base, but we don't have an href; find the first base
|
||||
// which does have an href, and set the document's first base to that.
|
||||
nsIContent* newBaseNode = FindBaseRecursive(doc);
|
||||
return doc->SetFirstBaseNodeWithHref(newBaseNode);
|
||||
IsInDoc() &&
|
||||
(head = GetParent()) &&
|
||||
head == GetOwnerDoc()->GetHeadContent()) {
|
||||
SetBaseURIUsingFirstBaseWithHref(head, nsnull);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -535,46 +521,46 @@ nsHTMLSharedElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The document stores a pointer to its first <base> element, which we may
|
||||
// need to update here.
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
if (mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::href) &&
|
||||
aDocument) {
|
||||
aDocument && aParent &&
|
||||
aDocument->GetHeadContent() == aParent) {
|
||||
|
||||
// If there's no <base> in the document, or if this comes before the one
|
||||
// that's currently there, set the document's first <base> to this.
|
||||
nsINode* curBaseNode = aDocument->GetFirstBaseNodeWithHref();
|
||||
if (!curBaseNode ||
|
||||
nsContentUtils::PositionIsBefore(this, curBaseNode)) {
|
||||
|
||||
aDocument->SetFirstBaseNodeWithHref(this);
|
||||
}
|
||||
SetBaseURIUsingFirstBaseWithHref(aParent, this);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLSharedElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = GetCurrentDoc();
|
||||
nsIDocument* doc;
|
||||
nsIContent* parent;
|
||||
PRBool inHeadBase = mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
(doc = GetCurrentDoc()) &&
|
||||
(parent = GetParent()) &&
|
||||
parent->NodeInfo()->Equals(nsGkAtoms::head,
|
||||
kNameSpaceID_XHTML);
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
// If we're removing a <base> from a document, we may need to update the
|
||||
// document's record of the first base node.
|
||||
if (doc && mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML)) {
|
||||
|
||||
// If we're not the first base node, then we don't need to do anything.
|
||||
if (this != doc->GetFirstBaseNodeWithHref())
|
||||
return;
|
||||
|
||||
// If we were the first base node, we need to find the new first base.
|
||||
|
||||
nsIContent* newBaseNode = FindBaseRecursive(doc);
|
||||
doc->SetFirstBaseNodeWithHref(newBaseNode);
|
||||
if (inHeadBase) {
|
||||
// We might have gotten here as a result of the <head> being removed
|
||||
// from the document. In that case we need to call SetBaseURI(nsnull)
|
||||
nsIContent* head = doc->GetHeadContent();
|
||||
if (head) {
|
||||
SetBaseURIUsingFirstBaseWithHref(head, nsnull);
|
||||
}
|
||||
else {
|
||||
doc->SetBaseURI(nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,9 +250,6 @@ protected:
|
||||
SinkContext* mHeadContext;
|
||||
PRInt32 mNumOpenIFRAMES;
|
||||
|
||||
nsCOMPtr<nsIURI> mBaseHref;
|
||||
nsCOMPtr<nsIAtom> mBaseTarget;
|
||||
|
||||
// depth of containment within <noembed>, <noframes> etc
|
||||
PRInt32 mInsideNoXXXTag;
|
||||
|
||||
@ -277,14 +274,6 @@ protected:
|
||||
|
||||
void StartLayout(PRBool aIgnorePendingSheets);
|
||||
|
||||
/**
|
||||
* AddBaseTagInfo adds the "current" base URI and target to the content node
|
||||
* in the form of bogo-attributes. This MUST be called before attributes are
|
||||
* added to the content node, since the way URI attributes are treated may
|
||||
* depend on the value of the base URI
|
||||
*/
|
||||
void AddBaseTagInfo(nsIContent* aContent);
|
||||
|
||||
// Routines for tags that require special handling
|
||||
nsresult CloseHTML();
|
||||
nsresult OpenFrameset(const nsIParserNode& aNode);
|
||||
@ -293,7 +282,6 @@ protected:
|
||||
nsresult CloseBody();
|
||||
nsresult OpenForm(const nsIParserNode& aNode);
|
||||
nsresult CloseForm();
|
||||
void ProcessBASEElement(nsGenericHTMLElement* aElement);
|
||||
nsresult ProcessLINKTag(const nsIParserNode& aNode);
|
||||
|
||||
// Routines for tags that require special handling when we reach their end
|
||||
@ -788,39 +776,6 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
||||
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
}
|
||||
|
||||
// Make sure to add base tag info, if needed, before setting any other
|
||||
// attributes -- what URI attrs do will depend on the base URI. Only do this
|
||||
// for elements that have useful URI attributes.
|
||||
// See bug 18478 and bug 30617 for why we need to do this.
|
||||
switch (nodeType) {
|
||||
// Containers with "href="
|
||||
case eHTMLTag_a:
|
||||
case eHTMLTag_map:
|
||||
|
||||
// Containers with "src="
|
||||
case eHTMLTag_script:
|
||||
|
||||
// Containers with "action="
|
||||
case eHTMLTag_form:
|
||||
|
||||
// Containers with "data="
|
||||
case eHTMLTag_object:
|
||||
|
||||
// Containers with "background="
|
||||
case eHTMLTag_table:
|
||||
case eHTMLTag_thead:
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_tr:
|
||||
case eHTMLTag_td:
|
||||
case eHTMLTag_th:
|
||||
mSink->AddBaseTagInfo(content);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rv = mSink->AddAttributes(aNode, content);
|
||||
MaybeSetForm(content, nodeType, mSink);
|
||||
@ -1047,28 +1002,8 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
|
||||
mSink->CreateContentObject(aNode, nodeType);
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Make sure to add base tag info, if needed, before setting any other
|
||||
// attributes -- what URI attrs do will depend on the base URI. Only do
|
||||
// this for elements that have useful URI attributes.
|
||||
// See bug 18478 and bug 30617 for why we need to do this.
|
||||
switch (nodeType) {
|
||||
case eHTMLTag_area:
|
||||
case eHTMLTag_meta:
|
||||
case eHTMLTag_img:
|
||||
case eHTMLTag_frame:
|
||||
case eHTMLTag_input:
|
||||
case eHTMLTag_embed:
|
||||
mSink->AddBaseTagInfo(content);
|
||||
break;
|
||||
|
||||
// <form> can end up as a leaf if it's misnested with table elements
|
||||
case eHTMLTag_form:
|
||||
mSink->AddBaseTagInfo(content);
|
||||
if (nodeType == eHTMLTag_form) {
|
||||
mSink->mCurrentForm = content;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rv = mSink->AddAttributes(aNode, content);
|
||||
@ -1082,12 +1017,6 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
|
||||
|
||||
// Additional processing needed once the element is in the tree
|
||||
switch (nodeType) {
|
||||
case eHTMLTag_base:
|
||||
if (!mSink->mInsideNoXXXTag) {
|
||||
mSink->ProcessBASEElement(content);
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_meta:
|
||||
// XXX It's just not sufficient to check if the parent is head. Also
|
||||
// check for the preference.
|
||||
@ -2630,28 +2559,6 @@ HTMLContentSink::StartLayout(PRBool aIgnorePendingSheets)
|
||||
nsContentSink::StartLayout(aIgnorePendingSheets);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLContentSink::AddBaseTagInfo(nsIContent* aContent)
|
||||
{
|
||||
nsresult rv;
|
||||
if (mBaseHref) {
|
||||
rv = aContent->SetProperty(nsGkAtoms::htmlBaseHref, mBaseHref,
|
||||
nsPropertyTable::SupportsDtorFunc, PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// circumvent nsDerivedSafe
|
||||
NS_ADDREF(static_cast<nsIURI*>(mBaseHref));
|
||||
}
|
||||
}
|
||||
if (mBaseTarget) {
|
||||
rv = aContent->SetProperty(nsGkAtoms::htmlBaseTarget, mBaseTarget,
|
||||
nsPropertyTable::SupportsDtorFunc, PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// circumvent nsDerivedSafe
|
||||
NS_ADDREF(static_cast<nsIAtom*>(mBaseTarget));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::OpenHeadContext()
|
||||
{
|
||||
@ -2703,56 +2610,6 @@ HTMLContentSink::CloseHeadContext()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HTMLContentSink::ProcessBASEElement(nsGenericHTMLElement* aElement)
|
||||
{
|
||||
// href attribute
|
||||
nsAutoString attrValue;
|
||||
if (aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, attrValue)) {
|
||||
//-- Make sure this page is allowed to load this URI
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> baseHrefURI;
|
||||
rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(baseHrefURI),
|
||||
attrValue, mDocument,
|
||||
nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
// Setting "BASE URI" from the last BASE tag appearing in HEAD.
|
||||
if (!mBody) {
|
||||
// The document checks if it is legal to set this base. Failing here is
|
||||
// ok, we just won't set a new base.
|
||||
rv = mDocument->SetBaseURI(baseHrefURI);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mDocumentBaseURI = mDocument->GetBaseURI();
|
||||
}
|
||||
} else {
|
||||
// NAV compatibility quirk
|
||||
|
||||
nsIScriptSecurityManager *securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
|
||||
rv = securityManager->
|
||||
CheckLoadURIWithPrincipal(mDocument->NodePrincipal(), baseHrefURI,
|
||||
nsIScriptSecurityManager::STANDARD);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mBaseHref = baseHrefURI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// target attribute
|
||||
if (aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::target, attrValue)) {
|
||||
if (!mBody) {
|
||||
// still in real HEAD
|
||||
mDocument->SetBaseTarget(attrValue);
|
||||
} else {
|
||||
// NAV compatibility quirk
|
||||
mBaseTarget = do_GetAtom(attrValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
|
||||
{
|
||||
@ -2781,7 +2638,6 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
|
||||
|
||||
// Add in the attributes and add the style content object to the
|
||||
// head container.
|
||||
AddBaseTagInfo(element);
|
||||
result = AddAttributes(aNode, element);
|
||||
if (NS_FAILED(result)) {
|
||||
return result;
|
||||
|
@ -136,9 +136,6 @@ public:
|
||||
nsresult AddText(const nsAString& aString);
|
||||
nsresult FlushText();
|
||||
|
||||
void ProcessBaseTag(nsIContent* aContent);
|
||||
void AddBaseTagInfo(nsIContent* aContent);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
PRPackedBool mAllContent;
|
||||
@ -156,9 +153,6 @@ public:
|
||||
PRInt32 mTextLength;
|
||||
PRInt32 mTextSize;
|
||||
|
||||
nsCOMPtr<nsIURI> mBaseHref;
|
||||
nsCOMPtr<nsIAtom> mBaseTarget;
|
||||
|
||||
nsCOMPtr<nsIDocument> mTargetDocument;
|
||||
nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
|
||||
|
||||
@ -328,63 +322,6 @@ nsHTMLFragmentContentSink::OpenHead()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLFragmentContentSink::ProcessBaseTag(nsIContent* aContent)
|
||||
{
|
||||
nsAutoString value;
|
||||
if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, value)) {
|
||||
nsCOMPtr<nsIURI> baseHrefURI;
|
||||
nsresult rv =
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(baseHrefURI),
|
||||
value, mTargetDocument,
|
||||
nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
nsIScriptSecurityManager *securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
|
||||
NS_ASSERTION(aContent->NodePrincipal() == mTargetDocument->NodePrincipal(),
|
||||
"How'd that happpen?");
|
||||
|
||||
rv = securityManager->
|
||||
CheckLoadURIWithPrincipal(mTargetDocument->NodePrincipal(), baseHrefURI,
|
||||
nsIScriptSecurityManager::STANDARD);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mBaseHref = baseHrefURI;
|
||||
}
|
||||
}
|
||||
if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::target, value)) {
|
||||
mBaseTarget = do_GetAtom(value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLFragmentContentSink::AddBaseTagInfo(nsIContent* aContent)
|
||||
{
|
||||
if (!aContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
if (mBaseHref) {
|
||||
rv = aContent->SetProperty(nsGkAtoms::htmlBaseHref, mBaseHref,
|
||||
nsPropertyTable::SupportsDtorFunc, PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// circumvent nsDerivedSafe
|
||||
NS_ADDREF(static_cast<nsIURI*>(mBaseHref));
|
||||
}
|
||||
}
|
||||
if (mBaseTarget) {
|
||||
rv = aContent->SetProperty(nsGkAtoms::htmlBaseTarget, mBaseTarget,
|
||||
nsPropertyTable::SupportsDtorFunc, PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// circumvent nsDerivedSafe
|
||||
NS_ADDREF(static_cast<nsIAtom*>(mBaseTarget));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode)
|
||||
{
|
||||
@ -459,16 +396,6 @@ nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode)
|
||||
|
||||
parent->AppendChildTo(content, PR_FALSE);
|
||||
PushContent(content);
|
||||
|
||||
if (nodeType == eHTMLTag_table
|
||||
|| nodeType == eHTMLTag_thead
|
||||
|| nodeType == eHTMLTag_tbody
|
||||
|| nodeType == eHTMLTag_tfoot
|
||||
|| nodeType == eHTMLTag_tr
|
||||
|| nodeType == eHTMLTag_td
|
||||
|| nodeType == eHTMLTag_th)
|
||||
// XXX if navigator_quirks_mode (only body in html supports background)
|
||||
AddBaseTagInfo(content);
|
||||
}
|
||||
else if (mProcessing && mIgnoreContainer) {
|
||||
mIgnoreContainer = PR_FALSE;
|
||||
@ -553,12 +480,6 @@ nsHTMLFragmentContentSink::AddLeaf(const nsIParserNode& aNode)
|
||||
}
|
||||
|
||||
parent->AppendChildTo(content, PR_FALSE);
|
||||
|
||||
if (nodeType == eHTMLTag_img || nodeType == eHTMLTag_frame
|
||||
|| nodeType == eHTMLTag_input) // elements with 'SRC='
|
||||
AddBaseTagInfo(content);
|
||||
else if (nodeType == eHTMLTag_base)
|
||||
ProcessBaseTag(content);
|
||||
}
|
||||
break;
|
||||
case eToken_text:
|
||||
@ -1073,16 +994,6 @@ nsHTMLParanoidFragmentSink::AddAttributes(const nsIParserNode& aNode,
|
||||
// Add attribute to content
|
||||
aContent->SetAttr(kNameSpaceID_None, keyAtom, v, PR_FALSE);
|
||||
}
|
||||
|
||||
if (nodeType == eHTMLTag_a ||
|
||||
nodeType == eHTMLTag_form ||
|
||||
nodeType == eHTMLTag_img ||
|
||||
nodeType == eHTMLTag_map ||
|
||||
nodeType == eHTMLTag_q ||
|
||||
nodeType == eHTMLTag_blockquote ||
|
||||
nodeType == eHTMLTag_input) {
|
||||
AddBaseTagInfo(aContent);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1150,21 +1061,8 @@ nsHTMLParanoidFragmentSink::AddLeaf(const nsIParserNode& aNode)
|
||||
rv = NameFromNode(aNode, getter_AddRefs(name));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We will process base tags, but we won't include them
|
||||
// in the output
|
||||
// Don't include base tags in output.
|
||||
if (name == nsGkAtoms::base) {
|
||||
nsCOMPtr<nsIContent> content;
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
nsIParserService* parserService = nsContentUtils::GetParserService();
|
||||
if (!parserService)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull,
|
||||
kNameSpaceID_XHTML);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
rv = NS_NewHTMLElement(getter_AddRefs(content), nodeInfo, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
AddAttributes(aNode, content);
|
||||
ProcessBaseTag(content);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -632,13 +632,7 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (nodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
!mHasProcessedBase) {
|
||||
// The first base wins
|
||||
ProcessBASETag(aContent);
|
||||
mHasProcessedBase = PR_TRUE;
|
||||
}
|
||||
else if (nodeInfo->Equals(nsGkAtoms::meta, kNameSpaceID_XHTML) &&
|
||||
if (nodeInfo->Equals(nsGkAtoms::meta, kNameSpaceID_XHTML) &&
|
||||
// Need to check here to make sure this meta tag does not set
|
||||
// mPrettyPrintXML to false when we have a special root!
|
||||
(!mPrettyPrintXML || !mPrettyPrintHasSpecialRoot)) {
|
||||
@ -756,7 +750,8 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIURI> url;
|
||||
rv = NS_NewURI(getter_AddRefs(url), aHref, nsnull, mDocumentBaseURI);
|
||||
rv = NS_NewURI(getter_AddRefs(url), aHref, nsnull,
|
||||
mDocument->GetBaseURI());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Do security check
|
||||
@ -797,32 +792,6 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLContentSink::ProcessBASETag(nsIContent* aContent)
|
||||
{
|
||||
NS_ASSERTION(aContent, "missing base-element");
|
||||
|
||||
if (mDocument) {
|
||||
nsAutoString value;
|
||||
|
||||
if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::target, value)) {
|
||||
mDocument->SetBaseTarget(value);
|
||||
}
|
||||
|
||||
if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, value)) {
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(baseURI), value);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mDocument->SetBaseURI(baseURI); // The document checks if it is legal to set this base
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mDocumentBaseURI = mDocument->GetBaseURI();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXMLContentSink::SetDocumentCharset(nsACString& aCharset)
|
||||
{
|
||||
|
@ -152,8 +152,6 @@ protected:
|
||||
void PopContent();
|
||||
PRBool HaveNotifiedForCurrentContent() const;
|
||||
|
||||
void ProcessBASETag(nsIContent* aContent);
|
||||
|
||||
nsresult FlushTags();
|
||||
|
||||
void UpdateChildCounts();
|
||||
@ -206,7 +204,6 @@ protected:
|
||||
PRUint8 mPrettyPrintXML : 1;
|
||||
PRUint8 mPrettyPrintHasSpecialRoot : 1;
|
||||
PRUint8 mPrettyPrintHasFactoredElements : 1;
|
||||
PRUint8 mHasProcessedBase : 1;
|
||||
PRUint8 mPrettyPrinting : 1; // True if we called PrettyPrint() and it
|
||||
// decided we should in fact prettyprint.
|
||||
|
||||
|
@ -86,7 +86,6 @@ txMozillaXMLOutput::txMozillaXMLOutput(const nsSubstring& aRootName,
|
||||
: mTreeDepth(0),
|
||||
mBadChildLevel(0),
|
||||
mTableState(NORMAL),
|
||||
mHaveBaseElement(PR_FALSE),
|
||||
mCreatingNewDocument(PR_TRUE),
|
||||
mOpenedElementIsHTML(PR_FALSE),
|
||||
mRootContentCreated(PR_FALSE),
|
||||
@ -111,7 +110,6 @@ txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat,
|
||||
: mTreeDepth(0),
|
||||
mBadChildLevel(0),
|
||||
mTableState(NORMAL),
|
||||
mHaveBaseElement(PR_FALSE),
|
||||
mCreatingNewDocument(PR_FALSE),
|
||||
mOpenedElementIsHTML(PR_FALSE),
|
||||
mRootContentCreated(PR_FALSE),
|
||||
@ -763,23 +761,6 @@ txMozillaXMLOutput::endHTMLElement(nsIContent* aElement)
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
else if (mCreatingNewDocument && atom == txHTMLAtoms::base &&
|
||||
!mHaveBaseElement) {
|
||||
// The first base wins
|
||||
mHaveBaseElement = PR_TRUE;
|
||||
|
||||
nsAutoString value;
|
||||
aElement->GetAttr(kNameSpaceID_None, txHTMLAtoms::target, value);
|
||||
mDocument->SetBaseTarget(value);
|
||||
|
||||
aElement->GetAttr(kNameSpaceID_None, txHTMLAtoms::href, value);
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
NS_NewURI(getter_AddRefs(baseURI), value, nsnull);
|
||||
|
||||
if (baseURI) {
|
||||
mDocument->SetBaseURI(baseURI); // The document checks if it is legal to set this base
|
||||
}
|
||||
}
|
||||
else if (mCreatingNewDocument && atom == txHTMLAtoms::meta) {
|
||||
// handle HTTP-EQUIV data
|
||||
nsAutoString httpEquiv;
|
||||
|
@ -153,8 +153,6 @@ private:
|
||||
|
||||
txOutputFormat mOutputFormat;
|
||||
|
||||
PRPackedBool mHaveBaseElement;
|
||||
|
||||
PRPackedBool mCreatingNewDocument;
|
||||
|
||||
PRPackedBool mOpenedElementIsHTML;
|
||||
|
@ -449,8 +449,6 @@ nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer,
|
||||
|
||||
Initialize(doc, uri, nsnull, nsnull);
|
||||
|
||||
// Initialize() doesn't deal with base URI
|
||||
mExecutor->SetBaseUriFromDocument();
|
||||
mExecutor->SetParser(this);
|
||||
mExecutor->SetNodeInfoManager(doc->NodeInfoManager());
|
||||
|
||||
|
@ -501,12 +501,6 @@ nsHtml5TreeBuilder::elementPopped(PRInt32 aNamespace, nsIAtom* aName, nsIContent
|
||||
treeOp->Init(eTreeOpDoneCreatingElement, aElement);
|
||||
return;
|
||||
}
|
||||
if (aName == nsHtml5Atoms::base) {
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(eTreeOpProcessBase, aElement);
|
||||
return;
|
||||
}
|
||||
if (aName == nsHtml5Atoms::meta) {
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
|
@ -603,34 +603,6 @@ nsHtml5TreeOpExecutor::FlushDocumentWrite()
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHtml5TreeOpExecutor::ProcessBASETag(nsIContent* aContent)
|
||||
{
|
||||
NS_ASSERTION(aContent, "missing base-element");
|
||||
if (mHasProcessedBase) {
|
||||
return NS_OK;
|
||||
}
|
||||
mHasProcessedBase = PR_TRUE;
|
||||
nsresult rv = NS_OK;
|
||||
if (mDocument) {
|
||||
nsAutoString value;
|
||||
if (aContent->GetAttr(kNameSpaceID_None, nsHtml5Atoms::target, value)) {
|
||||
mDocument->SetBaseTarget(value);
|
||||
}
|
||||
if (aContent->GetAttr(kNameSpaceID_None, nsHtml5Atoms::href, value)) {
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
rv = NS_NewURI(getter_AddRefs(baseURI), value);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mDocument->SetBaseURI(baseURI); // The document checks if it is legal to set this base
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mDocumentBaseURI = mDocument->GetBaseURI();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// copied from HTML content sink
|
||||
PRBool
|
||||
nsHtml5TreeOpExecutor::IsScriptEnabled()
|
||||
@ -827,7 +799,6 @@ nsHtml5TreeOpExecutor::GetTokenizer()
|
||||
void
|
||||
nsHtml5TreeOpExecutor::Reset() {
|
||||
DropHeldElements();
|
||||
mHasProcessedBase = PR_FALSE;
|
||||
mReadingFromStage = PR_FALSE;
|
||||
mOpQueue.Clear();
|
||||
mStarted = PR_FALSE;
|
||||
|
@ -97,7 +97,6 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
|
||||
*/
|
||||
PRBool mSuppressEOF;
|
||||
|
||||
PRBool mHasProcessedBase;
|
||||
PRBool mReadingFromStage;
|
||||
nsTArray<nsHtml5TreeOperation> mOpQueue;
|
||||
nsTArray<nsIContentPtr> mElementsSeenInThisAppendBatch;
|
||||
@ -188,7 +187,6 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
|
||||
virtual nsISupports *GetTarget();
|
||||
|
||||
// nsContentSink methods
|
||||
virtual nsresult ProcessBASETag(nsIContent* aContent);
|
||||
virtual void UpdateChildCounts();
|
||||
virtual nsresult FlushTags();
|
||||
virtual void PostEvaluateScript(nsIScriptElement *aElement);
|
||||
@ -214,11 +212,6 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
|
||||
return IsScriptExecutingImpl();
|
||||
}
|
||||
|
||||
void SetBaseUriFromDocument() {
|
||||
mDocumentBaseURI = mDocument->GetBaseURI();
|
||||
mHasProcessedBase = PR_TRUE;
|
||||
}
|
||||
|
||||
void SetNodeInfoManager(nsNodeInfoManager* aManager) {
|
||||
mNodeInfoManager = aManager;
|
||||
}
|
||||
|
@ -603,11 +603,6 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
||||
aBuilder->UpdateStyleSheet(node);
|
||||
return rv;
|
||||
}
|
||||
case eTreeOpProcessBase: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
rv = aBuilder->ProcessBASETag(node);
|
||||
return rv;
|
||||
}
|
||||
case eTreeOpProcessMeta: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
rv = aBuilder->ProcessMETATag(node);
|
||||
|
@ -74,7 +74,6 @@ enum eHtml5TreeOperation {
|
||||
eTreeOpSetDocumentCharset,
|
||||
eTreeOpNeedsCharsetSwitchTo,
|
||||
eTreeOpUpdateStyleSheet,
|
||||
eTreeOpProcessBase,
|
||||
eTreeOpProcessMeta,
|
||||
eTreeOpProcessOfflineManifest,
|
||||
eTreeOpMarkMalformedIfScript,
|
||||
|
Loading…
Reference in New Issue
Block a user