LCOV - code coverage report
Current view: top level - dom/html - HTMLImageElement.h (source / functions) Hit Total Coverage
Test: output.info Lines: 4 69 5.8 %
Date: 2017-07-14 16:53:18 Functions: 3 31 9.7 %
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             : #ifndef mozilla_dom_HTMLImageElement_h
       8             : #define mozilla_dom_HTMLImageElement_h
       9             : 
      10             : #include "mozilla/Attributes.h"
      11             : #include "nsGenericHTMLElement.h"
      12             : #include "nsImageLoadingContent.h"
      13             : #include "nsIDOMHTMLImageElement.h"
      14             : #include "imgRequestProxy.h"
      15             : #include "Units.h"
      16             : #include "nsCycleCollectionParticipant.h"
      17             : 
      18             : namespace mozilla {
      19             : class EventChainPreVisitor;
      20             : namespace dom {
      21             : 
      22             : class ImageLoadTask;
      23             : 
      24             : class ResponsiveImageSelector;
      25             : class HTMLImageElement final : public nsGenericHTMLElement,
      26             :                                public nsImageLoadingContent,
      27             :                                public nsIDOMHTMLImageElement
      28             : {
      29             :   friend class HTMLSourceElement;
      30             :   friend class HTMLPictureElement;
      31             :   friend class ImageLoadTask;
      32             : public:
      33             :   explicit HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
      34             : 
      35             :   static already_AddRefed<HTMLImageElement>
      36             :     Image(const GlobalObject& aGlobal,
      37             :           const Optional<uint32_t>& aWidth,
      38             :           const Optional<uint32_t>& aHeight,
      39             :           ErrorResult& aError);
      40             : 
      41           4 :   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLImageElement,
      42             :                                            nsGenericHTMLElement)
      43             : 
      44             :   // nsISupports
      45             :   NS_DECL_ISUPPORTS_INHERITED
      46             : 
      47             :   virtual bool Draggable() const override;
      48             : 
      49             :   // Element
      50             :   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
      51             : 
      52             :   // EventTarget
      53             :   virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
      54             : 
      55             :   // nsIDOMHTMLImageElement
      56             :   NS_DECL_NSIDOMHTMLIMAGEELEMENT
      57             : 
      58           0 :   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLImageElement, img)
      59             : 
      60             :   // override from nsImageLoadingContent
      61             :   CORSMode GetCORSMode() override;
      62             : 
      63             :   // nsIContent
      64             :   virtual bool ParseAttribute(int32_t aNamespaceID,
      65             :                                 nsIAtom* aAttribute,
      66             :                                 const nsAString& aValue,
      67             :                                 nsAttrValue& aResult) override;
      68             :   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
      69             :                                               int32_t aModType) const override;
      70             :   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
      71             :   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
      72             : 
      73             :   virtual nsresult GetEventTargetParent(
      74             :                      EventChainPreVisitor& aVisitor) override;
      75             : 
      76             :   bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
      77             : 
      78             :   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
      79             :                               nsIContent* aBindingParent,
      80             :                               bool aCompileEventHandlers) override;
      81             :   virtual void UnbindFromTree(bool aDeep, bool aNullParent) override;
      82             : 
      83             :   virtual EventStates IntrinsicState() const override;
      84             :   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
      85             :                          bool aPreallocateChildren) const override;
      86             : 
      87             :   virtual void NodeInfoChanged(nsIDocument* aOldDoc) override;
      88             : 
      89             :   nsresult CopyInnerTo(Element* aDest, bool aPreallocateChildren);
      90             : 
      91             :   void MaybeLoadImage(bool aAlwaysForceLoad);
      92             : 
      93           0 :   bool IsMap()
      94             :   {
      95           0 :     return GetBoolAttr(nsGkAtoms::ismap);
      96             :   }
      97           0 :   void SetIsMap(bool aIsMap, ErrorResult& aError)
      98             :   {
      99           0 :     SetHTMLBoolAttr(nsGkAtoms::ismap, aIsMap, aError);
     100           0 :   }
     101           0 :   uint32_t Width()
     102             :   {
     103           0 :     return GetWidthHeightForImage(mCurrentRequest).width;
     104             :   }
     105           0 :   void SetWidth(uint32_t aWidth, ErrorResult& aError)
     106             :   {
     107           0 :     SetUnsignedIntAttr(nsGkAtoms::width, aWidth, 0, aError);
     108           0 :   }
     109           0 :   uint32_t Height()
     110             :   {
     111           0 :     return GetWidthHeightForImage(mCurrentRequest).height;
     112             :   }
     113           0 :   void SetHeight(uint32_t aHeight, ErrorResult& aError)
     114             :   {
     115           0 :     SetUnsignedIntAttr(nsGkAtoms::height, aHeight, 0, aError);
     116           0 :   }
     117             :   uint32_t NaturalWidth();
     118             :   uint32_t NaturalHeight();
     119             :   bool Complete();
     120           0 :   uint32_t Hspace()
     121             :   {
     122           0 :     return GetUnsignedIntAttr(nsGkAtoms::hspace, 0);
     123             :   }
     124           0 :   void SetHspace(uint32_t aHspace, ErrorResult& aError)
     125             :   {
     126           0 :     SetUnsignedIntAttr(nsGkAtoms::hspace, aHspace, 0, aError);
     127           0 :   }
     128           0 :   uint32_t Vspace()
     129             :   {
     130           0 :     return GetUnsignedIntAttr(nsGkAtoms::vspace, 0);
     131             :   }
     132           0 :   void SetVspace(uint32_t aVspace, ErrorResult& aError)
     133             :   {
     134           0 :     SetUnsignedIntAttr(nsGkAtoms::vspace, aVspace, 0, aError);
     135           0 :   }
     136             : 
     137             :   // The XPCOM versions of the following getters work for Web IDL bindings as well
     138           0 :   void SetAlt(const nsAString& aAlt, ErrorResult& aError)
     139             :   {
     140           0 :     SetHTMLAttr(nsGkAtoms::alt, aAlt, aError);
     141           0 :   }
     142           0 :   void SetSrc(const nsAString& aSrc, ErrorResult& aError)
     143             :   {
     144           0 :     SetHTMLAttr(nsGkAtoms::src, aSrc, aError);
     145           0 :   }
     146           0 :   void SetSrcset(const nsAString& aSrcset, ErrorResult& aError)
     147             :   {
     148           0 :     SetHTMLAttr(nsGkAtoms::srcset, aSrcset, aError);
     149           0 :   }
     150           0 :   void GetCrossOrigin(nsAString& aResult)
     151             :   {
     152             :     // Null for both missing and invalid defaults is ok, since we
     153             :     // always parse to an enum value, so we don't need an invalid
     154             :     // default, and we _want_ the missing default to be null.
     155           0 :     GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aResult);
     156           0 :   }
     157           0 :   void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError)
     158             :   {
     159           0 :     SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
     160           0 :   }
     161           0 :   void SetUseMap(const nsAString& aUseMap, ErrorResult& aError)
     162             :   {
     163           0 :     SetHTMLAttr(nsGkAtoms::usemap, aUseMap, aError);
     164           0 :   }
     165           0 :   void SetName(const nsAString& aName, ErrorResult& aError)
     166             :   {
     167           0 :     SetHTMLAttr(nsGkAtoms::name, aName, aError);
     168           0 :   }
     169           0 :   void SetAlign(const nsAString& aAlign, ErrorResult& aError)
     170             :   {
     171           0 :     SetHTMLAttr(nsGkAtoms::align, aAlign, aError);
     172           0 :   }
     173           0 :   void SetLongDesc(const nsAString& aLongDesc, ErrorResult& aError)
     174             :   {
     175           0 :     SetHTMLAttr(nsGkAtoms::longdesc, aLongDesc, aError);
     176           0 :   }
     177           0 :   void SetSizes(const nsAString& aSizes, ErrorResult& aError)
     178             :   {
     179           0 :     SetHTMLAttr(nsGkAtoms::sizes, aSizes, aError);
     180           0 :   }
     181           0 :   void SetBorder(const nsAString& aBorder, ErrorResult& aError)
     182             :   {
     183           0 :     SetHTMLAttr(nsGkAtoms::border, aBorder, aError);
     184           0 :   }
     185           0 :   void SetReferrerPolicy(const nsAString& aReferrer, ErrorResult& aError)
     186             :   {
     187           0 :     SetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrer, aError);
     188           0 :   }
     189           0 :   void GetReferrerPolicy(nsAString& aReferrer)
     190             :   {
     191           0 :     GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrer);
     192           0 :   }
     193             : 
     194             :   net::ReferrerPolicy
     195           4 :   GetImageReferrerPolicy() override
     196             :   {
     197           4 :     return GetReferrerPolicyAsEnum();
     198             :   }
     199             : 
     200             :   int32_t X();
     201             :   int32_t Y();
     202             :   // Uses XPCOM GetLowsrc.
     203             :   void SetLowsrc(const nsAString& aLowsrc, ErrorResult& aError)
     204             :   {
     205             :     SetHTMLAttr(nsGkAtoms::lowsrc, aLowsrc, aError);
     206             :   }
     207             : 
     208             : #ifdef DEBUG
     209             :   nsIDOMHTMLFormElement* GetForm() const;
     210             : #endif
     211             :   void SetForm(nsIDOMHTMLFormElement* aForm);
     212             :   void ClearForm(bool aRemoveFromForm);
     213             : 
     214             :   virtual void DestroyContent() override;
     215             : 
     216             :   void MediaFeatureValuesChanged();
     217             : 
     218             :   /**
     219             :    * Given a hypothetical <img> or <source> tag with the given parameters,
     220             :    * return what URI we would attempt to use, if any.  Used by the preloader to
     221             :    * resolve sources prior to DOM creation.
     222             :    *
     223             :    * @param aDocument The document this image would be for, for referencing
     224             :    *        viewport width and DPI/zoom
     225             :    * @param aIsSourceTag If these parameters are for a <source> tag (as in a
     226             :    *        <picture>) rather than an <img> tag. Note that some attrs are unused
     227             :    *        when this is true an vice versa
     228             :    * @param aSrcAttr [ignored if aIsSourceTag] The src attr for this image.
     229             :    * @param aSrcsetAttr The srcset attr for this image/source
     230             :    * @param aSizesAttr The sizes attr for this image/source
     231             :    * @param aTypeAttr [ignored if !aIsSourceTag] The type attr for this source.
     232             :    *                  Should be a void string to differentiate no type attribute
     233             :    *                  from an empty one.
     234             :    * @param aMediaAttr [ignored if !aIsSourceTag] The media attr for this
     235             :    *                   source.  Should be a void string to differentiate no
     236             :    *                   media attribute from an empty one.
     237             :    * @param aResult A reference to store the resulting URL spec in if we
     238             :    *                selected a source.  This value is not guaranteed to parse to
     239             :    *                a valid URL, merely the URL that the tag would attempt to
     240             :    *                resolve and load (which may be the empty string).  This
     241             :    *                parameter is not modified if return value is false.
     242             :    * @return True if we were able to select a final source, false if further
     243             :    *         sources would be considered.  It follows that this always returns
     244             :    *         true if !aIsSourceTag.
     245             :    *
     246             :    * Note that the return value may be true with an empty string as the result,
     247             :    * which implies that the parameters provided describe a tag that would select
     248             :    * no source.  This is distinct from a return of false which implies that
     249             :    * further <source> or <img> tags would be considered.
     250             :    */
     251             :   static bool
     252             :     SelectSourceForTagWithAttrs(nsIDocument *aDocument,
     253             :                                 bool aIsSourceTag,
     254             :                                 const nsAString& aSrcAttr,
     255             :                                 const nsAString& aSrcsetAttr,
     256             :                                 const nsAString& aSizesAttr,
     257             :                                 const nsAString& aTypeAttr,
     258             :                                 const nsAString& aMediaAttr,
     259             :                                 nsAString& aResult);
     260             : 
     261             :   /**
     262             :    * If this image's src pointers to an SVG document, flush the SVG document's
     263             :    * use counters to telemetry.  Only used for testing purposes.
     264             :    */
     265             :   void FlushUseCounters();
     266             : 
     267             : protected:
     268             :   virtual ~HTMLImageElement();
     269             : 
     270             :   // Queues a task to run LoadSelectedImage pending stable state.
     271             :   //
     272             :   // Pending Bug 1076583 this is only used by the responsive image
     273             :   // algorithm (InResponsiveMode()) -- synchronous actions when just
     274             :   // using img.src will bypass this, and update source and kick off
     275             :   // image load synchronously.
     276             :   void QueueImageLoadTask(bool aAlwaysLoad);
     277             : 
     278             :   // True if we have a srcset attribute or a <picture> parent, regardless of if
     279             :   // any valid responsive sources were parsed from either.
     280             :   bool HaveSrcsetOrInPicture();
     281             : 
     282             :   // True if we are using the newer image loading algorithm. This will be the
     283             :   // only mode after Bug 1076583
     284             :   bool InResponsiveMode();
     285             : 
     286             :   // True if the given URL and density equal the last URL and density that was loaded by this element.
     287             :   bool SelectedSourceMatchesLast(nsIURI* aSelectedSource, double aSelectedDensity);
     288             : 
     289             :   // Resolve and load the current mResponsiveSelector (responsive mode) or src
     290             :   // attr image.
     291             :   nsresult LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad);
     292             : 
     293             :   // True if this string represents a type we would support on <source type>
     294             :   static bool SupportedPictureSourceType(const nsAString& aType);
     295             : 
     296             :   // Update/create/destroy mResponsiveSelector
     297             :   void PictureSourceSrcsetChanged(nsIContent *aSourceNode,
     298             :                                   const nsAString& aNewValue, bool aNotify);
     299             :   void PictureSourceSizesChanged(nsIContent *aSourceNode,
     300             :                                  const nsAString& aNewValue, bool aNotify);
     301             :   // As we re-run the source selection on these mutations regardless,
     302             :   // we don't actually care which changed or to what
     303             :   void PictureSourceMediaOrTypeChanged(nsIContent *aSourceNode, bool aNotify);
     304             : 
     305             :   void PictureSourceAdded(nsIContent *aSourceNode);
     306             :   // This should be called prior to the unbind, such that nextsibling works
     307             :   void PictureSourceRemoved(nsIContent *aSourceNode);
     308             : 
     309             :   // Re-evaluates all source nodes (picture <source>,<img>) and finds
     310             :   // the best source set for mResponsiveSelector. If a better source
     311             :   // is found, creates a new selector and feeds the source to it. If
     312             :   // the current ResponsiveSelector is not changed, runs
     313             :   // SelectImage(true) to re-evaluate its candidates.
     314             :   //
     315             :   // Because keeping the existing selector is the common case (and we
     316             :   // often do no-op reselections), this does not re-parse values for
     317             :   // the existing mResponsiveSelector, meaning you need to update its
     318             :   // parameters as appropriate before calling (or null it out to force
     319             :   // recreation)
     320             :   //
     321             :   // Returns true if the source has changed, and false otherwise.
     322             :   bool UpdateResponsiveSource();
     323             : 
     324             :   // Given a <source> node that is a previous sibling *or* ourselves, try to
     325             :   // create a ResponsiveSelector.
     326             : 
     327             :   // If the node's srcset/sizes make for an invalid selector, returns
     328             :   // false. This does not guarantee the resulting selector matches an image,
     329             :   // only that it is valid.
     330             :   bool TryCreateResponsiveSelector(nsIContent *aSourceNode);
     331             : 
     332             :   CSSIntPoint GetXY();
     333             :   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
     334             :   void UpdateFormOwner();
     335             : 
     336             :   virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
     337             :                                  const nsAttrValueOrString* aValue,
     338             :                                  bool aNotify) override;
     339             : 
     340             :   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
     341             :                                 const nsAttrValue* aValue,
     342             :                                 const nsAttrValue* aOldValue,
     343             :                                 bool aNotify) override;
     344             :   virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
     345             :                                           const nsAttrValueOrString& aValue,
     346             :                                           bool aNotify) override;
     347             : 
     348             :   // Override for nsImageLoadingContent.
     349          80 :   nsIContent* AsContent() override { return this; }
     350             : 
     351             :   // This is a weak reference that this element and the HTMLFormElement
     352             :   // cooperate in maintaining.
     353             :   HTMLFormElement* mForm;
     354             : 
     355             :   // Created when we're tracking responsive image state
     356             :   RefPtr<ResponsiveImageSelector> mResponsiveSelector;
     357             : 
     358             : private:
     359             :   bool SourceElementMatches(nsIContent* aSourceNode);
     360             : 
     361             :   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
     362             :                                     GenericSpecifiedValues* aGenericData);
     363             :   /**
     364             :    * This function is called by AfterSetAttr and OnAttrSetButNotChanged.
     365             :    * It will not be called if the value is being unset.
     366             :    *
     367             :    * @param aNamespaceID the namespace of the attr being set
     368             :    * @param aName the localname of the attribute being set
     369             :    * @param aValue the value it's being set to represented as either a string or
     370             :    *        a parsed nsAttrValue.
     371             :    * @param aOldValue the value previously set. Will be null if no value was
     372             :    *        previously set. This value should only be used when
     373             :    *        aValueMaybeChanged is true; when aValueMaybeChanged is false,
     374             :    *        aOldValue should be considered unreliable.
     375             :    * @param aValueMaybeChanged will be false when this function is called from
     376             :    *        OnAttrSetButNotChanged to indicate that the value was not changed.
     377             :    * @param aNotify Whether we plan to notify document observers.
     378             :    */
     379             :   void AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
     380             :                             const nsAttrValueOrString& aValue,
     381             :                             const nsAttrValue* aOldValue,
     382             :                             bool aValueMaybeChanged, bool aNotify);
     383             : 
     384             :   bool mInDocResponsiveContent;
     385             :   RefPtr<ImageLoadTask> mPendingImageLoadTask;
     386             : 
     387             :   // Last URL that was attempted to load by this element.
     388             :   nsCOMPtr<nsIURI> mLastSelectedSource;
     389             :   // Last pixel density that was selected.
     390             :   double mCurrentDensity;
     391             : };
     392             : 
     393             : } // namespace dom
     394             : } // namespace mozilla
     395             : 
     396             : #endif /* mozilla_dom_HTMLImageElement_h */

Generated by: LCOV version 1.13