Bug 1343964 part 4 - Have document and svg:use element own URLExtraData. r=bz,bholley
MozReview-Commit-ID: 8451L5qJvEx
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -19,16 +19,17 @@
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/DeclarationBlockInlines.h"
#include "mozilla/EffectSet.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/EventStates.h"
#include "mozilla/ServoRestyleManager.h"
+#include "mozilla/URLExtraData.h"
#include "mozilla/dom/Attr.h"
#include "nsDOMAttributeMap.h"
#include "nsIAtom.h"
#include "mozilla/dom/NodeInfo.h"
#include "mozilla/dom/Event.h"
#include "nsIDocumentInlines.h"
#include "nsIDocumentEncoder.h"
#include "nsIDOMNodeList.h"
@@ -343,17 +344,17 @@ nsIContent::LookupNamespaceURIInternal(c
already_AddRefed<nsIURI>
nsIContent::GetBaseURI(bool aTryUseXHRDocBaseURI) const
{
if (IsInAnonymousSubtree() && IsAnonymousContentInSVGUseSubtree()) {
nsIContent* bindingParent = GetBindingParent();
MOZ_ASSERT(bindingParent);
SVGUseElement* useElement = static_cast<SVGUseElement*>(bindingParent);
// XXX Ignore xml:base as we are removing it.
- return do_AddRef(useElement->GetContentBaseURI());
+ return do_AddRef(useElement->GetContentURLData()->BaseURI());
}
nsIDocument* doc = OwnerDoc();
// Start with document base
nsCOMPtr<nsIURI> base = doc->GetBaseURI(aTryUseXHRDocBaseURI);
// Collect array of xml:base attribute values up the parent chain. This
// is slightly slower for the case when there are xml:base attributes, but
@@ -413,17 +414,17 @@ nsIContent::GetBaseURI(bool aTryUseXHRDo
nsIURI*
nsIContent::GetBaseURIWithoutXMLBase() const
{
if (IsInAnonymousSubtree() && IsAnonymousContentInSVGUseSubtree()) {
nsIContent* bindingParent = GetBindingParent();
MOZ_ASSERT(bindingParent);
SVGUseElement* useElement = static_cast<SVGUseElement*>(bindingParent);
- return useElement->GetContentBaseURI();
+ return useElement->GetContentURLData()->BaseURI();
}
// This also ignores the case that SVG inside XBL binding.
// But it is probably fine.
return OwnerDoc()->GetDocBaseURI();
}
already_AddRefed<nsIURI>
nsIContent::GetBaseURIForStyleAttr() const
@@ -440,16 +441,33 @@ nsIContent::GetBaseURIForStyleAttr() con
if (!isEqual) {
doc->WarnOnceAbout(nsIDocument::eXMLBaseAttributeForStyleAttr);
}
}
return nsLayoutUtils::StyleAttrWithXMLBaseDisabled()
? do_AddRef(baseWithoutXMLBase) : base.forget();
}
+URLExtraData*
+nsIContent::GetURLDataForStyleAttr() const
+{
+ if (IsInAnonymousSubtree() && IsAnonymousContentInSVGUseSubtree()) {
+ nsIContent* bindingParent = GetBindingParent();
+ MOZ_ASSERT(bindingParent);
+ SVGUseElement* useElement = static_cast<SVGUseElement*>(bindingParent);
+ return useElement->GetContentURLData();
+ }
+ // We are not going to support xml:base for stylo, but we want to
+ // ensure we unship that support before we enabling stylo.
+ MOZ_ASSERT(nsLayoutUtils::StyleAttrWithXMLBaseDisabled());
+ // This also ignores the case that SVG inside XBL binding.
+ // But it is probably fine.
+ return OwnerDoc()->DefaultStyleAttrURLData();
+}
+
//----------------------------------------------------------------------
static inline JSObject*
GetJSObjectChild(nsWrapperCache* aCache)
{
return aCache->PreservingWrapper() ? aCache->GetWrapperPreserveColor() : nullptr;
}
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -16,16 +16,17 @@
#include "mozilla/AutoRestore.h"
#include "mozilla/BinarySearch.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/EffectSet.h"
#include "mozilla/IntegerRange.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Likely.h"
#include "mozilla/PresShell.h"
+#include "mozilla/URLExtraData.h"
#include <algorithm>
#include "mozilla/Logging.h"
#include "plstr.h"
#include "mozilla/Sprintf.h"
#include "mozilla/Telemetry.h"
#include "nsIInterfaceRequestor.h"
@@ -3578,16 +3579,37 @@ nsDocument::SetBaseURI(nsIURI* aURI)
if (aURI) {
mDocumentBaseURI = NS_TryToMakeImmutable(aURI);
} else {
mDocumentBaseURI = nullptr;
}
RefreshLinkHrefs();
}
+URLExtraData*
+nsIDocument::DefaultStyleAttrURLData()
+{
+#ifdef MOZ_STYLO
+ MOZ_ASSERT(NS_IsMainThread());
+ nsIURI* baseURI = GetDocBaseURI();
+ nsIURI* docURI = GetDocumentURI();
+ nsIPrincipal* principal = NodePrincipal();
+ if (!mCachedURLData ||
+ mCachedURLData->BaseURI() != baseURI ||
+ mCachedURLData->GetReferrer() != docURI ||
+ mCachedURLData->GetPrincipal() != principal) {
+ mCachedURLData = new URLExtraData(baseURI, docURI, principal);
+ }
+ return mCachedURLData;
+#else
+ MOZ_CRASH("Should not be called for non-stylo build");
+ return nullptr;
+#endif
+}
+
void
nsDocument::GetBaseTarget(nsAString &aBaseTarget)
{
aBaseTarget = mBaseTarget;
}
void
nsDocument::SetDocumentCharacterSet(const nsACString& aCharSetID)
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -19,16 +19,17 @@ class nsRuleWalker;
class nsAttrValue;
class nsAttrName;
class nsTextFragment;
class nsIFrame;
class nsXBLBinding;
namespace mozilla {
class EventChainPreVisitor;
+struct URLExtraData;
namespace dom {
class ShadowRoot;
} // namespace dom
namespace widget {
struct IMEState;
} // namespace widget
} // namespace mozilla
@@ -956,16 +957,19 @@ public:
}
// Overloaded from nsINode
virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const override;
// Returns base URI for style attribute.
already_AddRefed<nsIURI> GetBaseURIForStyleAttr() const;
+ // Returns the URL data for style attribute.
+ mozilla::URLExtraData* GetURLDataForStyleAttr() const;
+
virtual nsresult GetEventTargetParent(
mozilla::EventChainPreVisitor& aVisitor) override;
virtual bool IsPurple() = 0;
virtual void RemovePurple() = 0;
virtual bool OwnedOnlyByTheDOMTree() { return false; }
protected:
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -105,16 +105,17 @@ struct nsCSSSelectorList;
namespace mozilla {
class AbstractThread;
class CSSStyleSheet;
class ErrorResult;
class EventStates;
class PendingAnimationTracker;
class StyleSetHandle;
template<typename> class OwningNonNull;
+struct URLExtraData;
namespace css {
class Loader;
class ImageLoader;
class Rule;
} // namespace css
namespace dom {
@@ -480,16 +481,25 @@ public:
}
return GetFallbackBaseURI();
}
virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const override;
virtual void SetBaseURI(nsIURI* aURI) = 0;
/**
+ * Return the URL data which style system needs for resolving url value.
+ * This method attempts to use the cached object in mCachedURLData, but
+ * if the base URI, document URI, or principal has changed since last
+ * call to this function, or the function is called the first time for
+ * the document, a new one is created.
+ */
+ mozilla::URLExtraData* DefaultStyleAttrURLData();
+
+ /**
* Get/Set the base target of a link in a document.
*/
virtual void GetBaseTarget(nsAString &aBaseTarget) = 0;
void SetBaseTarget(const nsString& aBaseTarget) {
mBaseTarget = aBaseTarget;
}
/**
@@ -2979,16 +2989,21 @@ protected:
nsString mLastModified;
nsCOMPtr<nsIURI> mDocumentURI;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mChromeXHRDocURI;
nsCOMPtr<nsIURI> mDocumentBaseURI;
nsCOMPtr<nsIURI> mChromeXHRDocBaseURI;
+#ifdef MOZ_STYLO
+ // A lazily-constructed URL data for style system to resolve URL value.
+ RefPtr<mozilla::URLExtraData> mCachedURLData;
+#endif
+
nsWeakPtr mDocumentLoadGroup;
bool mReferrerPolicySet;
ReferrerPolicyEnum mReferrerPolicy;
bool mBlockAllMixedContent;
bool mBlockAllMixedContentPreloads;
bool mUpgradeInsecureRequests;
--- a/dom/svg/SVGUseElement.cpp
+++ b/dom/svg/SVGUseElement.cpp
@@ -10,16 +10,17 @@
#include "mozilla/dom/SVGUseElementBinding.h"
#include "nsGkAtoms.h"
#include "mozilla/dom/SVGSVGElement.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "mozilla/dom/Element.h"
#include "nsContentUtils.h"
#include "nsIURI.h"
+#include "mozilla/URLExtraData.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Use)
namespace mozilla {
namespace dom {
JSObject*
SVGUseElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
@@ -322,20 +323,23 @@ SVGUseElement::CreateAnonymousContent()
if (mLengthAttributes[ATTR_WIDTH].IsExplicitlySet())
newElement->SetLength(nsGkAtoms::width, mLengthAttributes[ATTR_WIDTH]);
if (mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet())
newElement->SetLength(nsGkAtoms::height, mLengthAttributes[ATTR_HEIGHT]);
}
// Store the base URI
- mContentBaseURI = targetContent->GetBaseURI();
- if (!mContentBaseURI) {
+ nsCOMPtr<nsIURI> baseURI = targetContent->GetBaseURI();
+ if (!baseURI) {
return nullptr;
}
+ mContentURLData = new URLExtraData(baseURI.forget(),
+ do_AddRef(OwnerDoc()->GetDocumentURI()),
+ do_AddRef(NodePrincipal()));
targetContent->AddMutationObserver(this);
mClone = newcontent;
#ifdef DEBUG
// Our anonymous clone can get restyled by various things
// (e.g. SMIL). Reconstructing its frame is OK, though, because
// it's going to be our _only_ child in the frame tree, so can't get
--- a/dom/svg/SVGUseElement.h
+++ b/dom/svg/SVGUseElement.h
@@ -21,16 +21,18 @@ class nsSVGUseFrame;
nsresult
NS_NewSVGSVGElement(nsIContent **aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser);
nsresult NS_NewSVGUseElement(nsIContent **aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
namespace mozilla {
+struct URLExtraData;
+
namespace dom {
typedef SVGGraphicsElement SVGUseElementBase;
class SVGUseElement final : public SVGUseElementBase,
public nsStubMutationObserver
{
friend class ::nsSVGUseFrame;
@@ -72,17 +74,17 @@ public:
// WebIDL
already_AddRefed<SVGAnimatedString> Href();
already_AddRefed<SVGAnimatedLength> X();
already_AddRefed<SVGAnimatedLength> Y();
already_AddRefed<SVGAnimatedLength> Width();
already_AddRefed<SVGAnimatedLength> Height();
nsIURI* GetSourceDocURI();
- nsIURI* GetContentBaseURI() const { return mContentBaseURI; }
+ URLExtraData* GetContentURLData() const { return mContentURLData; }
protected:
class SourceReference : public nsReferencedElement {
public:
explicit SourceReference(SVGUseElement* aContainer) : mContainer(aContainer) {}
protected:
virtual void ElementChanged(Element* aFrom, Element* aTo) override {
nsReferencedElement::ElementChanged(aFrom, aTo);
@@ -115,15 +117,15 @@ protected:
enum { HREF, XLINK_HREF };
nsSVGString mStringAttributes[2];
static StringInfo sStringInfo[2];
nsCOMPtr<nsIContent> mOriginal; // if we've been cloned, our "real" copy
nsCOMPtr<nsIContent> mClone; // cloned tree
SourceReference mSource; // observed element
- nsCOMPtr<nsIURI> mContentBaseURI; // Base URI for its anonymous content
+ RefPtr<URLExtraData> mContentURLData; // URL data for its anonymous content
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGUseElement_h