Bug 723441. Add a way to store base URI object on nodes out-of-band, and use the for <use>-cloned content. r=dholbert

This commit is contained in:
Boris Zbarsky 2012-02-02 15:50:50 -05:00
parent 6eabf9235f
commit c9cb72c0b1
7 changed files with 4996 additions and 5 deletions

View File

@ -51,6 +51,7 @@
#include "jspubtd.h"
#include "nsDOMMemoryReporter.h"
#include "nsIVariant.h"
#include "nsGkAtoms.h"
// Including 'windows.h' will #define GetClassInfo to something else.
#ifdef XP_WIN
@ -994,6 +995,22 @@ public:
*/
virtual already_AddRefed<nsIURI> GetBaseURI() const = 0;
/**
* Facility for explicitly setting a base URI on a node.
*/
nsresult SetExplicitBaseURI(nsIURI* aURI);
/**
* The explicit base URI, if set, otherwise null
*/
protected:
nsIURI* GetExplicitBaseURI() const {
if (HasExplicitBaseURI()) {
return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));
}
return nsnull;
}
public:
nsresult GetDOMBaseURI(nsAString &aURI) const;
// Note! This function must never fail. It only return an nsresult so that
@ -1230,6 +1247,8 @@ private:
// Maybe set if the node is a root of a subtree
// which needs to be kept in the purple buffer.
NodeIsPurpleRoot,
// Set if the node has an explicit base URI stored
NodeHasExplicitBaseURI,
// Guard value
BooleanFlagCount
};
@ -1300,6 +1319,8 @@ protected:
void ClearHasName() { ClearBoolFlag(ElementHasName); }
void SetMayHaveContentEditableAttr()
{ SetBoolFlag(ElementMayHaveContentEditableAttr); }
bool HasExplicitBaseURI() const { return GetBoolFlag(NodeHasExplicitBaseURI); }
void SetHasExplicitBaseURI() { SetBoolFlag(NodeHasExplicitBaseURI); }
public:
// Optimized way to get classinfo.

View File

@ -1537,6 +1537,12 @@ nsIContent::GetBaseURI() const
}
}
}
nsIURI* explicitBaseURI = elem->GetExplicitBaseURI();
if (explicitBaseURI) {
base = explicitBaseURI;
break;
}
// Otherwise check for xml:base attribute
elem->GetAttr(kNameSpaceID_XML, nsGkAtoms::base, attr);
@ -1566,6 +1572,27 @@ nsIContent::GetBaseURI() const
return base.forget();
}
static void
ReleaseURI(void*, /* aObject*/
nsIAtom*, /* aPropertyName */
void* aPropertyValue,
void* /* aData */)
{
nsIURI* uri = static_cast<nsIURI*>(aPropertyValue);
NS_RELEASE(uri);
}
nsresult
nsINode::SetExplicitBaseURI(nsIURI* aURI)
{
nsresult rv = SetProperty(nsGkAtoms::baseURIProperty, aURI, ReleaseURI);
if (NS_SUCCEEDED(rv)) {
SetHasExplicitBaseURI();
NS_ADDREF(aURI);
}
return rv;
}
//----------------------------------------------------------------------
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsChildContentList)

View File

@ -1851,6 +1851,7 @@ GK_ATOM(transitionsOfBeforeProperty, "TransitionsOfBeforeProperty") // FrameTran
GK_ATOM(transitionsOfAfterProperty, "TransitionsOfAfterProperty") // FrameTransitions*
GK_ATOM(genConInitializerProperty, "QuoteNodeProperty")
GK_ATOM(labelMouseDownPtProperty, "LabelMouseDownPtProperty")
GK_ATOM(baseURIProperty, "baseURIProperty")
// Languages for lang-specific transforms
GK_ATOM(Japanese, "ja")

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html class="reftest-wait">
<body>
<img id="x">
<script>
var xhr = new XMLHttpRequest();
xhr.open("GET", "723441-resource.svg");
xhr.overrideMimeType( 'text/plain; charset=x-user-defined' );
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var svg = xhr.responseText.replace(/#/g, '%23');
var img = document.getElementById("x");
img.onload = function() {
document.documentElement.className = "";
}
img.src = "data:image/svg+xml;," + svg;
}
}
xhr.send();
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 422 KiB

View File

@ -58,3 +58,4 @@ load 603145-1.svg
load 613899-1.svg
load 613899-2.svg
load zero-size-image.svg
load 723441-1.html

View File

@ -267,7 +267,7 @@ nsSVGUseElement::CreateAnonymousContent()
LookupHref();
nsIContent* targetContent = mSource.get();
if (!targetContent)
if (!targetContent || !targetContent->IsSVG())
return nsnull;
// make sure target is valid type for <use>
@ -391,10 +391,7 @@ nsSVGUseElement::CreateAnonymousContent()
nsCOMPtr<nsIURI> baseURI = targetContent->GetBaseURI();
if (!baseURI)
return nsnull;
nsCAutoString spec;
baseURI->GetSpec(spec);
newcontent->SetAttr(kNameSpaceID_XML, nsGkAtoms::base,
NS_ConvertUTF8toUTF16(spec), false);
newcontent->SetExplicitBaseURI(baseURI);
targetContent->AddMutationObserver(this);
mClone = newcontent;