Bug 265894 - Part 1. Implement SVGSVGElement::CloneFromSymbol.
1. Move clone-svg-from-symbol logic out of SVGUseElement::CreateAnonymousContent.
2. Since we move the clone logic into SVGSVGElement::CloneFromSymbol, it's easier
to setup SVGSVGElement::mCloneFromSymbol just inside this new function in
next patch.
MozReview-Commit-ID: 6nxhz3AGV5t
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -1185,10 +1185,62 @@ SVGSVGElement::GetIntrinsicHeight()
// Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue
// that uses the passed argument as the context, but that's fine since we
// know the length isn't a percentage so the context won't be used (and we
// need to pass the element to be able to resolve em/ex units).
float height = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(this);
return nsSVGUtils::ClampToInt(height);
}
+/* static */
+already_AddRefed<nsIContent>
+SVGSVGElement::CloneFromSymbol(Element* aShadowHost, nsIContent* aSymbol)
+{
+ MOZ_ASSERT(aSymbol->IsSVGElement(nsGkAtoms::symbol));
+ nsIDocument *document = aShadowHost->GetComposedDoc();
+ if (!document) {
+ return nullptr;
+ }
+
+ nsNodeInfoManager *nodeInfoManager = document->NodeInfoManager();
+ if (!nodeInfoManager) {
+ return nullptr;
+ }
+
+ RefPtr<mozilla::dom::NodeInfo> nodeInfo;
+ nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::svg, nullptr,
+ kNameSpaceID_SVG,
+ nsIDOMNode::ELEMENT_NODE);
+
+ nsCOMPtr<nsIContent> svgNode;
+ NS_NewSVGSVGElement(getter_AddRefs(svgNode), nodeInfo.forget(),
+ NOT_FROM_PARSER);
+
+ if (!svgNode) {
+ return nullptr;
+ }
+
+ // copy attributes
+ BorrowedAttrInfo info;
+ uint32_t i;
+ for (i = 0; (info = aSymbol->GetAttrInfoAt(i)); i++) {
+ nsAutoString value;
+ int32_t nsID = info.mName->NamespaceID();
+ nsIAtom* lname = info.mName->LocalName();
+
+ info.mValue->ToString(value);
+
+ svgNode->SetAttr(nsID, lname, info.mName->GetPrefix(), value, false);
+ }
+
+ // move the children over
+ uint32_t num = aSymbol->GetChildCount();
+ for (i = 0; i < num; i++) {
+ nsCOMPtr<nsIContent> child = aSymbol->GetFirstChild();
+ aSymbol->RemoveChildAt(0, false);
+ svgNode->InsertChildAt(child, i, true);
+ }
+
+ return svgNode.forget();
+}
+
} // namespace dom
} // namespace mozilla
--- a/dom/svg/SVGSVGElement.h
+++ b/dom/svg/SVGSVGElement.h
@@ -252,16 +252,18 @@ public:
return svgFloatSize(mViewportWidth, mViewportHeight);
}
void SetViewportSize(const svgFloatSize& aSize) {
mViewportWidth = aSize.width;
mViewportHeight = aSize.height;
}
+ static already_AddRefed<nsIContent> CloneFromSymbol(Element* aShadowHost,
+ nsIContent* aSymbol);
// WebIDL
already_AddRefed<SVGAnimatedLength> X();
already_AddRefed<SVGAnimatedLength> Y();
already_AddRefed<SVGAnimatedLength> Width();
already_AddRefed<SVGAnimatedLength> Height();
float PixelUnitToMillimeterX();
float PixelUnitToMillimeterY();
float ScreenPixelToMillimeterX();
--- a/dom/svg/SVGUseElement.cpp
+++ b/dom/svg/SVGUseElement.cpp
@@ -271,58 +271,20 @@ SVGUseElement::CreateAnonymousContent()
getter_AddRefs(newnode));
nsCOMPtr<nsIContent> newcontent = do_QueryInterface(newnode);
if (!newcontent)
return nullptr;
if (newcontent->IsSVGElement(nsGkAtoms::symbol)) {
- nsIDocument *document = GetComposedDoc();
- if (!document)
- return nullptr;
-
- nsNodeInfoManager *nodeInfoManager = document->NodeInfoManager();
- if (!nodeInfoManager)
- return nullptr;
-
- RefPtr<mozilla::dom::NodeInfo> nodeInfo;
- nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::svg, nullptr,
- kNameSpaceID_SVG,
- nsIDOMNode::ELEMENT_NODE);
-
- nsCOMPtr<nsIContent> svgNode;
- NS_NewSVGSVGElement(getter_AddRefs(svgNode), nodeInfo.forget(),
- NOT_FROM_PARSER);
-
- if (!svgNode)
+ newcontent = SVGSVGElement::CloneFromSymbol(this, newcontent);
+ if (!newcontent) {
return nullptr;
-
- // copy attributes
- BorrowedAttrInfo info;
- uint32_t i;
- for (i = 0; (info = newcontent->GetAttrInfoAt(i)); i++) {
- nsAutoString value;
- int32_t nsID = info.mName->NamespaceID();
- nsIAtom* lname = info.mName->LocalName();
-
- info.mValue->ToString(value);
-
- svgNode->SetAttr(nsID, lname, info.mName->GetPrefix(), value, false);
}
-
- // move the children over
- uint32_t num = newcontent->GetChildCount();
- for (i = 0; i < num; i++) {
- nsCOMPtr<nsIContent> child = newcontent->GetFirstChild();
- newcontent->RemoveChildAt(0, false);
- svgNode->InsertChildAt(child, i, true);
- }
-
- newcontent = svgNode;
}
if (newcontent->IsAnyOfSVGElements(nsGkAtoms::svg, nsGkAtoms::symbol)) {
nsSVGElement *newElement = static_cast<nsSVGElement*>(newcontent.get());
if (mLengthAttributes[ATTR_WIDTH].IsExplicitlySet())
newElement->SetLength(nsGkAtoms::width, mLengthAttributes[ATTR_WIDTH]);
if (mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet())