LCOV - code coverage report
Current view: top level - dom/svg - SVGMPathElement.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 107 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 22 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/ArrayUtils.h"
       8             : 
       9             : #include "mozilla/dom/SVGMPathElement.h"
      10             : #include "nsDebug.h"
      11             : #include "mozilla/dom/SVGAnimateMotionElement.h"
      12             : #include "mozilla/dom/SVGPathElement.h"
      13             : #include "nsContentUtils.h"
      14             : #include "mozilla/dom/SVGMPathElementBinding.h"
      15             : #include "nsIURI.h"
      16             : 
      17           0 : NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(MPath)
      18             : 
      19             : namespace mozilla {
      20             : namespace dom {
      21             : 
      22             : JSObject*
      23           0 : SVGMPathElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
      24             : {
      25           0 :   return SVGMPathElementBinding::Wrap(aCx, this, aGivenProto);
      26             : }
      27             : 
      28             : nsSVGElement::StringInfo SVGMPathElement::sStringInfo[2] =
      29             : {
      30             :   { &nsGkAtoms::href, kNameSpaceID_None, false },
      31             :   { &nsGkAtoms::href, kNameSpaceID_XLink, false }
      32             : };
      33             : 
      34             : // Cycle collection magic -- based on SVGUseElement
      35             : NS_IMPL_CYCLE_COLLECTION_CLASS(SVGMPathElement)
      36             : 
      37           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGMPathElement,
      38             :                                                 SVGMPathElementBase)
      39           0 :   tmp->UnlinkHrefTarget(false);
      40           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      41             : 
      42           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGMPathElement,
      43             :                                                   SVGMPathElementBase)
      44           0 :   tmp->mHrefTarget.Traverse(&cb);
      45           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      46             : 
      47             : //----------------------------------------------------------------------
      48             : // nsISupports methods
      49             : 
      50           0 : NS_IMPL_ADDREF_INHERITED(SVGMPathElement,SVGMPathElementBase)
      51           0 : NS_IMPL_RELEASE_INHERITED(SVGMPathElement,SVGMPathElementBase)
      52             : 
      53           0 : NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGMPathElement)
      54           0 :   NS_INTERFACE_TABLE_INHERITED(SVGMPathElement, nsIDOMNode, nsIDOMElement,
      55             :                                nsIDOMSVGElement,
      56             :                                nsIMutationObserver)
      57           0 : NS_INTERFACE_TABLE_TAIL_INHERITING(SVGMPathElementBase)
      58             : 
      59             : // Constructor
      60           0 : SVGMPathElement::SVGMPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
      61             :   : SVGMPathElementBase(aNodeInfo),
      62           0 :     mHrefTarget(this)
      63             : {
      64           0 : }
      65             : 
      66           0 : SVGMPathElement::~SVGMPathElement()
      67             : {
      68           0 :   UnlinkHrefTarget(false);
      69           0 : }
      70             : 
      71             : //----------------------------------------------------------------------
      72             : // nsIDOMNode methods
      73             : 
      74           0 : NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGMPathElement)
      75             : 
      76             : already_AddRefed<SVGAnimatedString>
      77           0 : SVGMPathElement::Href()
      78             : {
      79           0 :   return mStringAttributes[HREF].IsExplicitlySet()
      80             :          ? mStringAttributes[HREF].ToDOMAnimatedString(this)
      81           0 :          : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
      82             : }
      83             : 
      84             : //----------------------------------------------------------------------
      85             : // nsIContent methods
      86             : 
      87             : nsresult
      88           0 : SVGMPathElement::BindToTree(nsIDocument* aDocument,
      89             :                             nsIContent* aParent,
      90             :                             nsIContent* aBindingParent,
      91             :                             bool aCompileEventHandlers)
      92             : {
      93           0 :   MOZ_ASSERT(!mHrefTarget.get(),
      94             :              "Shouldn't have href-target yet (or it should've been cleared)");
      95           0 :   nsresult rv = SVGMPathElementBase::BindToTree(aDocument, aParent,
      96             :                                                 aBindingParent,
      97           0 :                                                 aCompileEventHandlers);
      98           0 :   NS_ENSURE_SUCCESS(rv,rv);
      99             : 
     100           0 :   if (aDocument) {
     101             :     const nsAttrValue* hrefAttrValue =
     102           0 :       HasAttr(kNameSpaceID_None, nsGkAtoms::href)
     103           0 :       ? mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_None)
     104           0 :       : mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_XLink);
     105           0 :     if (hrefAttrValue) {
     106           0 :       UpdateHrefTarget(aParent, hrefAttrValue->GetStringValue());
     107             :     }
     108             :   }
     109             : 
     110           0 :   return NS_OK;
     111             : }
     112             : 
     113             : void
     114           0 : SVGMPathElement::UnbindFromTree(bool aDeep, bool aNullParent)
     115             : {
     116           0 :   UnlinkHrefTarget(true);
     117           0 :   SVGMPathElementBase::UnbindFromTree(aDeep, aNullParent);
     118           0 : }
     119             : 
     120             : bool
     121           0 : SVGMPathElement::ParseAttribute(int32_t aNamespaceID,
     122             :                                 nsIAtom* aAttribute,
     123             :                                 const nsAString& aValue,
     124             :                                 nsAttrValue& aResult)
     125             : {
     126             :   bool returnVal =
     127           0 :     SVGMPathElementBase::ParseAttribute(aNamespaceID, aAttribute,
     128           0 :                                           aValue, aResult);
     129           0 :   if ((aNamespaceID == kNameSpaceID_XLink ||
     130           0 :        aNamespaceID == kNameSpaceID_None ) &&
     131           0 :       aAttribute == nsGkAtoms::href &&
     132           0 :       IsInUncomposedDoc()) {
     133             :     // Note: If we fail the IsInDoc call, it's ok -- we'll update the target
     134             :     // on next BindToTree call.
     135             : 
     136             :     // Note: "href" takes priority over xlink:href. So if "xlink:href" is being
     137             :     // set here, we only let that update our target if "href" is *unset*.
     138           0 :     if (aNamespaceID != kNameSpaceID_XLink ||
     139           0 :         !mStringAttributes[HREF].IsExplicitlySet()) {
     140           0 :       UpdateHrefTarget(GetParent(), aValue);
     141             :     }
     142             :   }
     143           0 :   return returnVal;
     144             : }
     145             : 
     146             : nsresult
     147           0 : SVGMPathElement::UnsetAttr(int32_t aNamespaceID,
     148             :                            nsIAtom* aAttribute, bool aNotify)
     149             : {
     150           0 :   nsresult rv = SVGMPathElementBase::UnsetAttr(aNamespaceID, aAttribute,
     151           0 :                                                aNotify);
     152           0 :   NS_ENSURE_SUCCESS(rv, rv);
     153             : 
     154           0 :   if (aAttribute == nsGkAtoms::href) {
     155           0 :     if (aNamespaceID == kNameSpaceID_None) {
     156           0 :       UnlinkHrefTarget(true);
     157             : 
     158             :       // After unsetting href, we may still have xlink:href, so we should
     159             :       // try to add it back.
     160             :       const nsAttrValue* xlinkHref =
     161           0 :         mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_XLink);
     162           0 :       if (xlinkHref) {
     163           0 :         UpdateHrefTarget(GetParent(), xlinkHref->GetStringValue());
     164             :       }
     165           0 :     } else if (!HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
     166           0 :       UnlinkHrefTarget(true);
     167             :     } // else: we unset xlink:href, but we still have href attribute, so keep
     168             :       // the target linking to href.
     169             :   }
     170             : 
     171           0 :   return NS_OK;
     172             : }
     173             : 
     174             : //----------------------------------------------------------------------
     175             : // nsSVGElement methods
     176             : 
     177             : nsSVGElement::StringAttributesInfo
     178           0 : SVGMPathElement::GetStringInfo()
     179             : {
     180             :   return StringAttributesInfo(mStringAttributes, sStringInfo,
     181           0 :                               ArrayLength(sStringInfo));
     182             : }
     183             : 
     184             : //----------------------------------------------------------------------
     185             : // nsIMutationObserver methods
     186             : 
     187             : void
     188           0 : SVGMPathElement::AttributeChanged(nsIDocument* aDocument,
     189             :                                   Element* aElement,
     190             :                                   int32_t aNameSpaceID,
     191             :                                   nsIAtom* aAttribute,
     192             :                                   int32_t aModType,
     193             :                                   const nsAttrValue* aOldValue)
     194             : {
     195           0 :   if (aNameSpaceID == kNameSpaceID_None) {
     196           0 :     if (aAttribute == nsGkAtoms::d) {
     197           0 :       NotifyParentOfMpathChange(GetParent());
     198             :     }
     199             :   }
     200           0 : }
     201             : 
     202             : //----------------------------------------------------------------------
     203             : // Public helper methods
     204             : 
     205             : SVGPathElement*
     206           0 : SVGMPathElement::GetReferencedPath()
     207             : {
     208           0 :   if (!HasAttr(kNameSpaceID_XLink, nsGkAtoms::href) &&
     209           0 :       !HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
     210           0 :     MOZ_ASSERT(!mHrefTarget.get(),
     211             :                "We shouldn't have a href target "
     212             :                "if we don't have an xlink:href or href attribute");
     213           0 :     return nullptr;
     214             :   }
     215             : 
     216           0 :   nsIContent* genericTarget = mHrefTarget.get();
     217           0 :   if (genericTarget && genericTarget->IsSVGElement(nsGkAtoms::path)) {
     218           0 :     return static_cast<SVGPathElement*>(genericTarget);
     219             :   }
     220           0 :   return nullptr;
     221             : }
     222             : 
     223             : //----------------------------------------------------------------------
     224             : // Protected helper methods
     225             : 
     226             : void
     227           0 : SVGMPathElement::UpdateHrefTarget(nsIContent* aParent,
     228             :                                   const nsAString& aHrefStr)
     229             : {
     230           0 :   nsCOMPtr<nsIURI> targetURI;
     231           0 :   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
     232           0 :   nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI),
     233           0 :                                             aHrefStr, OwnerDoc(), baseURI);
     234             : 
     235             :   // Stop observing old target (if any)
     236           0 :   if (mHrefTarget.get()) {
     237           0 :     mHrefTarget.get()->RemoveMutationObserver(this);
     238             :   }
     239             : 
     240           0 :   if (aParent) {
     241             :     // Pass in |aParent| instead of |this| -- first argument is only used
     242             :     // for a call to GetComposedDoc(), and |this| might not have a current
     243             :     // document yet (if our caller is BindToTree).
     244           0 :     mHrefTarget.Reset(aParent, targetURI);
     245             :   } else {
     246             :     // if we don't have a parent, then there's no animateMotion element
     247             :     // depending on our target, so there's no point tracking it right now.
     248           0 :     mHrefTarget.Unlink();
     249             :   }
     250             : 
     251             :   // Start observing new target (if any)
     252           0 :   if (mHrefTarget.get()) {
     253           0 :     mHrefTarget.get()->AddMutationObserver(this);
     254             :   }
     255             : 
     256           0 :   NotifyParentOfMpathChange(aParent);
     257           0 : }
     258             : 
     259             : void
     260           0 : SVGMPathElement::UnlinkHrefTarget(bool aNotifyParent)
     261             : {
     262             :   // Stop observing old target (if any)
     263           0 :   if (mHrefTarget.get()) {
     264           0 :     mHrefTarget.get()->RemoveMutationObserver(this);
     265             :   }
     266           0 :   mHrefTarget.Unlink();
     267             : 
     268           0 :   if (aNotifyParent) {
     269           0 :     NotifyParentOfMpathChange(GetParent());
     270             :   }
     271           0 : }
     272             : 
     273             : void
     274           0 : SVGMPathElement::NotifyParentOfMpathChange(nsIContent* aParent)
     275             : {
     276           0 :   if (aParent && aParent->IsSVGElement(nsGkAtoms::animateMotion)) {
     277             : 
     278             :     SVGAnimateMotionElement* animateMotionParent =
     279           0 :       static_cast<SVGAnimateMotionElement*>(aParent);
     280             : 
     281           0 :     animateMotionParent->MpathChanged();
     282           0 :     AnimationNeedsResample();
     283             :   }
     284           0 : }
     285             : 
     286             : } // namespace dom
     287             : } // namespace mozilla
     288             : 

Generated by: LCOV version 1.13