LCOV - code coverage report
Current view: top level - dom/svg - SVGAElement.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 138 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 31 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/dom/SVGAElement.h"
       8             : 
       9             : #include "mozilla/Attributes.h"
      10             : #include "mozilla/EventDispatcher.h"
      11             : #include "mozilla/EventStates.h"
      12             : #include "mozilla/dom/SVGAElementBinding.h"
      13             : #include "nsCOMPtr.h"
      14             : #include "nsContentUtils.h"
      15             : #include "nsGkAtoms.h"
      16             : #include "nsSVGString.h"
      17             : #include "nsIURI.h"
      18             : 
      19           0 : NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(A)
      20             : 
      21             : namespace mozilla {
      22             : namespace dom {
      23             : 
      24             : JSObject*
      25           0 : SVGAElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
      26             : {
      27           0 :   return SVGAElementBinding::Wrap(aCx, this, aGivenProto);
      28             : }
      29             : 
      30             : nsSVGElement::StringInfo SVGAElement::sStringInfo[3] =
      31             : {
      32             :   { &nsGkAtoms::href, kNameSpaceID_None, true },
      33             :   { &nsGkAtoms::href, kNameSpaceID_XLink, true },
      34             :   { &nsGkAtoms::target, kNameSpaceID_None, true }
      35             : };
      36             : 
      37             : 
      38             : //----------------------------------------------------------------------
      39             : // nsISupports methods
      40             : 
      41           0 : NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGAElement)
      42           0 :   NS_INTERFACE_TABLE_INHERITED(SVGAElement,
      43             :                                nsIDOMNode,
      44             :                                nsIDOMElement,
      45             :                                nsIDOMSVGElement,
      46             :                                Link)
      47           0 : NS_INTERFACE_TABLE_TAIL_INHERITING(SVGAElementBase)
      48             : 
      49             : NS_IMPL_CYCLE_COLLECTION_CLASS(SVGAElement)
      50             : 
      51           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGAElement,
      52             :                                                   SVGAElementBase)
      53           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      54             : 
      55           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGAElement,
      56             :                                                 SVGAElementBase)
      57           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      58             : 
      59           0 : NS_IMPL_ADDREF_INHERITED(SVGAElement, SVGAElementBase)
      60           0 : NS_IMPL_RELEASE_INHERITED(SVGAElement, SVGAElementBase)
      61             : 
      62             : //----------------------------------------------------------------------
      63             : // Implementation
      64             : 
      65           0 : SVGAElement::SVGAElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
      66             :   : SVGAElementBase(aNodeInfo)
      67           0 :   , Link(this)
      68             : {
      69           0 : }
      70             : 
      71           0 : SVGAElement::~SVGAElement()
      72             : {
      73           0 : }
      74             : 
      75             : already_AddRefed<SVGAnimatedString>
      76           0 : SVGAElement::Href()
      77             : {
      78           0 :   return mStringAttributes[HREF].IsExplicitlySet()
      79             :          ? mStringAttributes[HREF].ToDOMAnimatedString(this)
      80           0 :          : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
      81             : }
      82             : 
      83             : //----------------------------------------------------------------------
      84             : // Link methods
      85             : 
      86             : bool
      87           0 : SVGAElement::ElementHasHref() const
      88             : {
      89           0 :   return mStringAttributes[HREF].IsExplicitlySet() ||
      90           0 :          mStringAttributes[XLINK_HREF].IsExplicitlySet();
      91             : }
      92             : 
      93             : //----------------------------------------------------------------------
      94             : // nsINode methods
      95             : 
      96             : nsresult
      97           0 : SVGAElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
      98             : {
      99           0 :   nsresult rv = Element::GetEventTargetParent(aVisitor);
     100           0 :   NS_ENSURE_SUCCESS(rv, rv);
     101             : 
     102           0 :   return GetEventTargetParentForLinks(aVisitor);
     103             : }
     104             : 
     105             : nsresult
     106           0 : SVGAElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
     107             : {
     108           0 :   return PostHandleEventForLinks(aVisitor);
     109             : }
     110             : 
     111           0 : NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGAElement)
     112             : 
     113             : 
     114             : //----------------------------------------------------------------------
     115             : 
     116             : already_AddRefed<SVGAnimatedString>
     117           0 : SVGAElement::Target()
     118             : {
     119           0 :   return mStringAttributes[TARGET].ToDOMAnimatedString(this);
     120             : }
     121             : 
     122             : void
     123           0 : SVGAElement::GetDownload(nsAString & aDownload)
     124             : {
     125           0 :   GetAttr(kNameSpaceID_None, nsGkAtoms::download, aDownload);
     126           0 : }
     127             : 
     128             : void
     129           0 : SVGAElement::SetDownload(const nsAString & aDownload, ErrorResult& rv)
     130             : {
     131           0 :   rv = SetAttr(kNameSpaceID_None, nsGkAtoms::download, aDownload, true);
     132           0 : }
     133             : 
     134             : //----------------------------------------------------------------------
     135             : // nsIContent methods
     136             : 
     137             : nsresult
     138           0 : SVGAElement::BindToTree(nsIDocument *aDocument, nsIContent *aParent,
     139             :                         nsIContent *aBindingParent,
     140             :                         bool aCompileEventHandlers)
     141             : {
     142           0 :   Link::ResetLinkState(false, Link::ElementHasHref());
     143             : 
     144           0 :   nsresult rv = SVGAElementBase::BindToTree(aDocument, aParent,
     145             :                                             aBindingParent,
     146           0 :                                             aCompileEventHandlers);
     147           0 :   NS_ENSURE_SUCCESS(rv, rv);
     148             : 
     149           0 :   nsIDocument* doc = GetComposedDoc();
     150           0 :   if (doc) {
     151           0 :     doc->RegisterPendingLinkUpdate(this);
     152             :   }
     153             : 
     154           0 :   return NS_OK;
     155             : }
     156             : 
     157             : void
     158           0 : SVGAElement::UnbindFromTree(bool aDeep, bool aNullParent)
     159             : {
     160             :   // If this link is ever reinserted into a document, it might
     161             :   // be under a different xml:base, so forget the cached state now.
     162           0 :   Link::ResetLinkState(false, Link::ElementHasHref());
     163             : 
     164           0 :   SVGAElementBase::UnbindFromTree(aDeep, aNullParent);
     165           0 : }
     166             : 
     167             : already_AddRefed<nsIURI>
     168           0 : SVGAElement::GetHrefURI() const
     169             : {
     170           0 :   nsCOMPtr<nsIURI> hrefURI;
     171           0 :   return IsLink(getter_AddRefs(hrefURI)) ? hrefURI.forget() : nullptr;
     172             : }
     173             : 
     174             : 
     175             : NS_IMETHODIMP_(bool)
     176           0 : SVGAElement::IsAttributeMapped(const nsIAtom* name) const
     177             : {
     178             :   static const MappedAttributeEntry* const map[] = {
     179             :     sFEFloodMap,
     180             :     sFiltersMap,
     181             :     sFontSpecificationMap,
     182             :     sGradientStopMap,
     183             :     sLightingEffectsMap,
     184             :     sMarkersMap,
     185             :     sTextContentElementsMap,
     186             :     sViewportsMap
     187             :   };
     188             : 
     189           0 :   return FindAttributeDependence(name, map) ||
     190           0 :     SVGAElementBase::IsAttributeMapped(name);
     191             : }
     192             : 
     193             : int32_t
     194           0 : SVGAElement::TabIndexDefault()
     195             : {
     196           0 :   return 0;
     197             : }
     198             : 
     199             : static bool
     200           0 : IsNodeInEditableRegion(nsINode* aNode)
     201             : {
     202           0 :   while (aNode) {
     203           0 :     if (aNode->IsEditable()) {
     204           0 :       return true;
     205             :     }
     206           0 :     aNode = aNode->GetParent();
     207             :   }
     208           0 :   return false;
     209             : }
     210             : 
     211             : bool
     212           0 : SVGAElement::IsSVGFocusable(bool* aIsFocusable, int32_t* aTabIndex)
     213             : {
     214           0 :   if (nsSVGElement::IsSVGFocusable(aIsFocusable, aTabIndex)) {
     215           0 :     return true;
     216             :   }
     217             : 
     218             :   // cannot focus links if there is no link handler
     219           0 :   nsIDocument* doc = GetComposedDoc();
     220           0 :   if (doc) {
     221           0 :     nsIPresShell* presShell = doc->GetShell();
     222           0 :     if (presShell) {
     223           0 :       nsPresContext* presContext = presShell->GetPresContext();
     224           0 :       if (presContext && !presContext->GetLinkHandler()) {
     225           0 :         *aIsFocusable = false;
     226           0 :         return false;
     227             :       }
     228             :     }
     229             :   }
     230             : 
     231             :   // Links that are in an editable region should never be focusable, even if
     232             :   // they are in a contenteditable="false" region.
     233           0 :   if (IsNodeInEditableRegion(this)) {
     234           0 :     if (aTabIndex) {
     235           0 :       *aTabIndex = -1;
     236             :     }
     237             : 
     238           0 :     *aIsFocusable = false;
     239             : 
     240           0 :     return true;
     241             :   }
     242             : 
     243           0 :   if (!HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)) {
     244             :     // check whether we're actually a link
     245           0 :     if (!Link::HasURI()) {
     246             :       // Not tabbable or focusable without href (bug 17605), unless
     247             :       // forced to be via presence of nonnegative tabindex attribute
     248           0 :       if (aTabIndex) {
     249           0 :         *aTabIndex = -1;
     250             :       }
     251             : 
     252           0 :       *aIsFocusable = false;
     253             : 
     254           0 :       return false;
     255             :     }
     256             :   }
     257             : 
     258           0 :   if (aTabIndex && (sTabFocusModel & eTabFocus_linksMask) == 0) {
     259           0 :     *aTabIndex = -1;
     260             :   }
     261             : 
     262           0 :   *aIsFocusable = true;
     263             : 
     264           0 :   return false;
     265             : }
     266             : 
     267             : bool
     268           0 : SVGAElement::IsLink(nsIURI** aURI) const
     269             : {
     270             :   // To be a clickable XLink for styling and interaction purposes, we require:
     271             :   //
     272             :   //   xlink:href    - must be set
     273             :   //   xlink:type    - must be unset or set to "" or set to "simple"
     274             :   //   xlink:show    - must be unset or set to "", "new" or "replace"
     275             :   //   xlink:actuate - must be unset or set to "" or "onRequest"
     276             :   //
     277             :   // For any other values, we're either not a *clickable* XLink, or the end
     278             :   // result is poorly specified. Either way, we return false.
     279             : 
     280             :   static nsIContent::AttrValuesArray sTypeVals[] =
     281             :     { &nsGkAtoms::_empty, &nsGkAtoms::simple, nullptr };
     282             : 
     283             :   static nsIContent::AttrValuesArray sShowVals[] =
     284             :     { &nsGkAtoms::_empty, &nsGkAtoms::_new, &nsGkAtoms::replace, nullptr };
     285             : 
     286             :   static nsIContent::AttrValuesArray sActuateVals[] =
     287             :     { &nsGkAtoms::_empty, &nsGkAtoms::onRequest, nullptr };
     288             : 
     289             :   // Optimization: check for href first for early return
     290           0 :   bool useBareHref = mStringAttributes[HREF].IsExplicitlySet();
     291             : 
     292           0 :   if ((useBareHref || mStringAttributes[XLINK_HREF].IsExplicitlySet()) &&
     293           0 :       FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::type,
     294           0 :                       sTypeVals, eCaseMatters) !=
     295           0 :                       nsIContent::ATTR_VALUE_NO_MATCH &&
     296           0 :       FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::show,
     297           0 :                       sShowVals, eCaseMatters) !=
     298           0 :                       nsIContent::ATTR_VALUE_NO_MATCH &&
     299           0 :       FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::actuate,
     300           0 :                       sActuateVals, eCaseMatters) !=
     301             :                       nsIContent::ATTR_VALUE_NO_MATCH) {
     302           0 :     nsCOMPtr<nsIURI> baseURI = GetBaseURI();
     303             :     // Get absolute URI
     304           0 :     nsAutoString str;
     305           0 :     const uint8_t idx = useBareHref ? HREF : XLINK_HREF;
     306           0 :     mStringAttributes[idx].GetAnimValue(str, this);
     307           0 :     nsContentUtils::NewURIWithDocumentCharset(aURI, str, OwnerDoc(), baseURI);
     308             :     // must promise out param is non-null if we return true
     309           0 :     return !!*aURI;
     310             :   }
     311             : 
     312           0 :   *aURI = nullptr;
     313           0 :   return false;
     314             : }
     315             : 
     316             : void
     317           0 : SVGAElement::GetLinkTarget(nsAString& aTarget)
     318             : {
     319           0 :   mStringAttributes[TARGET].GetAnimValue(aTarget, this);
     320           0 :   if (aTarget.IsEmpty()) {
     321             : 
     322             :     static nsIContent::AttrValuesArray sShowVals[] =
     323             :       { &nsGkAtoms::_new, &nsGkAtoms::replace, nullptr };
     324             : 
     325           0 :     switch (FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::show,
     326           0 :                             sShowVals, eCaseMatters)) {
     327             :     case 0:
     328           0 :       aTarget.AssignLiteral("_blank");
     329           0 :       return;
     330             :     case 1:
     331           0 :       return;
     332             :     }
     333           0 :     nsIDocument* ownerDoc = OwnerDoc();
     334           0 :     if (ownerDoc) {
     335           0 :       ownerDoc->GetBaseTarget(aTarget);
     336             :     }
     337             :   }
     338             : }
     339             : 
     340             : EventStates
     341           0 : SVGAElement::IntrinsicState() const
     342             : {
     343           0 :   return Link::LinkState() | SVGAElementBase::IntrinsicState();
     344             : }
     345             : 
     346             : nsresult
     347           0 : SVGAElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
     348             :                      nsIAtom* aPrefix, const nsAString& aValue,
     349             :                      bool aNotify)
     350             : {
     351           0 :   nsresult rv = SVGAElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
     352           0 :                                          aValue, aNotify);
     353             : 
     354             :   // The ordering of the parent class's SetAttr call and Link::ResetLinkState
     355             :   // is important here!  The attribute is not set until SetAttr returns, and
     356             :   // we will need the updated attribute value because notifying the document
     357             :   // that content states have changed will call IntrinsicState, which will try
     358             :   // to get updated information about the visitedness from Link.
     359           0 :   if (aName == nsGkAtoms::href &&
     360           0 :       (aNameSpaceID == kNameSpaceID_XLink ||
     361             :        aNameSpaceID == kNameSpaceID_None)) {
     362           0 :     Link::ResetLinkState(!!aNotify, true);
     363             :   }
     364             : 
     365           0 :   return rv;
     366             : }
     367             : 
     368             : nsresult
     369           0 : SVGAElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr,
     370             :                        bool aNotify)
     371             : {
     372           0 :   nsresult rv = nsSVGElement::UnsetAttr(aNameSpaceID, aAttr, aNotify);
     373             : 
     374             :   // The ordering of the parent class's UnsetAttr call and Link::ResetLinkState
     375             :   // is important here!  The attribute is not unset until UnsetAttr returns, and
     376             :   // we will need the updated attribute value because notifying the document
     377             :   // that content states have changed will call IntrinsicState, which will try
     378             :   // to get updated information about the visitedness from Link.
     379           0 :   if (aAttr == nsGkAtoms::href &&
     380           0 :       (aNameSpaceID == kNameSpaceID_XLink ||
     381             :        aNameSpaceID == kNameSpaceID_None)) {
     382           0 :     Link::ResetLinkState(!!aNotify, Link::ElementHasHref());
     383             :   }
     384             : 
     385           0 :   return rv;
     386             : }
     387             : 
     388             : //----------------------------------------------------------------------
     389             : // nsSVGElement methods
     390             : 
     391             : nsSVGElement::StringAttributesInfo
     392           0 : SVGAElement::GetStringInfo()
     393             : {
     394             :   return StringAttributesInfo(mStringAttributes, sStringInfo,
     395           0 :                               ArrayLength(sStringInfo));
     396             : }
     397             : 
     398             : } // namespace dom
     399             : } // namespace mozilla

Generated by: LCOV version 1.13