LCOV - code coverage report
Current view: top level - dom/events - EventStates.h (source / functions) Hit Total Coverage
Test: output.info Lines: 31 41 75.6 %
Date: 2017-07-14 16:53:18 Functions: 13 17 76.5 %
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_EventStates_h_
       8             : #define mozilla_EventStates_h_
       9             : 
      10             : #include "mozilla/Attributes.h"
      11             : #include "nsDebug.h"
      12             : 
      13             : namespace mozilla {
      14             : 
      15             : /**
      16             :  * EventStates is the class used to represent the event states of nsIContent
      17             :  * instances. These states are calculated by IntrinsicState() and
      18             :  * ContentStatesChanged() has to be called when one of them changes thus
      19             :  * informing the layout/style engine of the change.
      20             :  * Event states are associated with pseudo-classes.
      21             :  */
      22             : class EventStates
      23             : {
      24             : public:
      25             :   typedef uint64_t InternalType;
      26             :   typedef uint64_t ServoType;
      27             : 
      28       49518 :   constexpr EventStates()
      29       49518 :     : mStates(0)
      30             :   {
      31       49518 :   }
      32             : 
      33             :   // NOTE: the ideal scenario would be to have the default constructor public
      34             :   // setting mStates to 0 and this constructor (without = 0) private.
      35             :   // In that case, we could be sure that only macros at the end were creating
      36             :   // EventStates instances with mStates set to something else than 0.
      37             :   // Unfortunately, this constructor is needed at at least two places now.
      38      434346 :   explicit constexpr EventStates(InternalType aStates)
      39      434346 :     : mStates(aStates)
      40             :   {
      41      434346 :   }
      42             : 
      43      156453 :   EventStates constexpr operator|(const EventStates& aEventStates) const
      44             :   {
      45      312906 :     return EventStates(mStates | aEventStates.mStates);
      46             :   }
      47             : 
      48        7750 :   EventStates& operator|=(const EventStates& aEventStates)
      49             :   {
      50        7750 :     mStates |= aEventStates.mStates;
      51        7750 :     return *this;
      52             :   }
      53             : 
      54             :   // NOTE: calling if (eventStates1 & eventStates2) will not build.
      55             :   // This might work correctly if operator bool() is defined
      56             :   // but using HasState, HasAllStates or HasAtLeastOneOfStates is recommended.
      57        5711 :   EventStates constexpr operator&(const EventStates& aEventStates) const
      58             :   {
      59        5711 :     return EventStates(mStates & aEventStates.mStates);
      60             :   }
      61             : 
      62        1570 :   EventStates& operator&=(const EventStates& aEventStates)
      63             :   {
      64        1570 :     mStates &= aEventStates.mStates;
      65        1570 :     return *this;
      66             :   }
      67             : 
      68          31 :   bool operator==(const EventStates& aEventStates) const
      69             :   {
      70          31 :     return mStates == aEventStates.mStates;
      71             :   }
      72             : 
      73        5501 :   bool operator!=(const EventStates& aEventStates) const
      74             :   {
      75        5501 :     return mStates != aEventStates.mStates;
      76             :   }
      77             : 
      78        1615 :   EventStates operator~() const
      79             :   {
      80        1615 :     return EventStates(~mStates);
      81             :   }
      82             : 
      83         616 :   EventStates operator^(const EventStates& aEventStates) const
      84             :   {
      85         616 :     return EventStates(mStates ^ aEventStates.mStates);
      86             :   }
      87             : 
      88           0 :   EventStates& operator^=(const EventStates& aEventStates)
      89             :   {
      90           0 :     mStates ^= aEventStates.mStates;
      91           0 :     return *this;
      92             :   }
      93             : 
      94             :   /**
      95             :    * Returns true if the EventStates instance is empty.
      96             :    * A EventStates instance is empty if it contains no state.
      97             :    *
      98             :    * @return Whether if the object is empty.
      99             :    */
     100      245696 :   bool IsEmpty() const
     101             :   {
     102      245696 :     return mStates == 0;
     103             :   }
     104             : 
     105             :   /**
     106             :    * Returns true if the EventStates instance contains the state
     107             :    * contained in aEventStates.
     108             :    * @note aEventStates should contain only one state.
     109             :    *
     110             :    * @param aEventStates The state to check.
     111             :    *
     112             :    * @return Whether the object has the state from aEventStates
     113             :    */
     114        8692 :   bool HasState(EventStates aEventStates) const
     115             :   {
     116             : #ifdef DEBUG
     117             :     // If aEventStates.mStates is a power of two, it contains only one state
     118             :     // (or none, but we don't really care).
     119        8692 :     if ((aEventStates.mStates & (aEventStates.mStates - 1))) {
     120           0 :       NS_ERROR("When calling HasState, "
     121             :                "EventStates object has to contain only one state!");
     122             :     }
     123             : #endif // DEBUG
     124        8692 :     return mStates & aEventStates.mStates;
     125             :   }
     126             : 
     127             :   /**
     128             :    * Returns true if the EventStates instance contains one of the states
     129             :    * contained in aEventStates.
     130             :    *
     131             :    * @param aEventStates The states to check.
     132             :    *
     133             :    * @return Whether the object has at least one state from aEventStates
     134             :    */
     135      139038 :   bool HasAtLeastOneOfStates(EventStates aEventStates) const
     136             :   {
     137      139038 :     return mStates & aEventStates.mStates;
     138             :   }
     139             : 
     140             :   /**
     141             :    * Returns true if the EventStates instance contains all states
     142             :    * contained in aEventStates.
     143             :    *
     144             :    * @param aEventStates The states to check.
     145             :    *
     146             :    * @return Whether the object has all states from aEventStates
     147             :    */
     148           0 :   bool HasAllStates(EventStates aEventStates) const
     149             :   {
     150           0 :     return (mStates & aEventStates.mStates) == aEventStates.mStates;
     151             :   }
     152             : 
     153             :   // We only need that method for inDOMUtils::GetContentState.
     154             :   // If inDOMUtils::GetContentState is removed, this method should be removed.
     155           0 :   InternalType GetInternalValue() const {
     156           0 :     return mStates;
     157             :   }
     158             : 
     159             :   /**
     160             :    * Method used to get the appropriate state representation for Servo.
     161             :    */
     162           0 :   ServoType ServoValue() const
     163             :   {
     164           0 :     return mStates;
     165             :   }
     166             : 
     167             : private:
     168             :   InternalType mStates;
     169             : };
     170             : 
     171             : } // namespace mozilla
     172             : 
     173             : /**
     174             :  * The following macros are creating EventStates instance with different
     175             :  * values depending of their meaning.
     176             :  * Ideally, EventStates instance with values different than 0 should only be
     177             :  * created that way.
     178             :  */
     179             : 
     180             : // Helper to define a new EventStates macro.
     181             : #define NS_DEFINE_EVENT_STATE_MACRO(_val)               \
     182             :   (mozilla::EventStates(mozilla::EventStates::InternalType(1) << _val))
     183             : 
     184             : /*
     185             :  * In order to efficiently convert Gecko EventState values into Servo
     186             :  * ElementState values [1], we maintain the invariant that the low bits of
     187             :  * EventState can be masked off to form an ElementState (this works so
     188             :  * long as Servo never supports a state that Gecko doesn't).
     189             :  *
     190             :  * This is unfortunately rather fragile for now, but we should soon have
     191             :  * the infrastructure to statically-assert that these match up. If you
     192             :  * need to change these, please notify somebody involved with Stylo.
     193             :  *
     194             :  * [1] https://github.com/servo/servo/blob/master/components/style/element_state.rs
     195             :  */
     196             : 
     197             : // Mouse is down on content.
     198             : #define NS_EVENT_STATE_ACTIVE        NS_DEFINE_EVENT_STATE_MACRO(0)
     199             : // Content has focus.
     200             : #define NS_EVENT_STATE_FOCUS         NS_DEFINE_EVENT_STATE_MACRO(1)
     201             : // Mouse is hovering over content.
     202             : #define NS_EVENT_STATE_HOVER         NS_DEFINE_EVENT_STATE_MACRO(2)
     203             : // Content is enabled (and can be disabled).
     204             : #define NS_EVENT_STATE_ENABLED       NS_DEFINE_EVENT_STATE_MACRO(3)
     205             : // Content is disabled.
     206             : #define NS_EVENT_STATE_DISABLED      NS_DEFINE_EVENT_STATE_MACRO(4)
     207             : // Content is checked.
     208             : #define NS_EVENT_STATE_CHECKED       NS_DEFINE_EVENT_STATE_MACRO(5)
     209             : // Content is in the indeterminate state.
     210             : #define NS_EVENT_STATE_INDETERMINATE NS_DEFINE_EVENT_STATE_MACRO(6)
     211             : // Content shows its placeholder
     212             : #define NS_EVENT_STATE_PLACEHOLDERSHOWN NS_DEFINE_EVENT_STATE_MACRO(7)
     213             : // Content is URL's target (ref).
     214             : #define NS_EVENT_STATE_URLTARGET     NS_DEFINE_EVENT_STATE_MACRO(8)
     215             : // Content is the full screen element, or a frame containing the
     216             : // current full-screen element.
     217             : #define NS_EVENT_STATE_FULL_SCREEN   NS_DEFINE_EVENT_STATE_MACRO(9)
     218             : // Content is valid (and can be invalid).
     219             : #define NS_EVENT_STATE_VALID         NS_DEFINE_EVENT_STATE_MACRO(10)
     220             : // Content is invalid.
     221             : #define NS_EVENT_STATE_INVALID       NS_DEFINE_EVENT_STATE_MACRO(11)
     222             : // UI friendly version of :valid pseudo-class.
     223             : #define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(12)
     224             : // UI friendly version of :invalid pseudo-class.
     225             : #define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(13)
     226             : // Content could not be rendered (image/object/etc).
     227             : #define NS_EVENT_STATE_BROKEN        NS_DEFINE_EVENT_STATE_MACRO(14)
     228             : // Content disabled by the user (images turned off, say).
     229             : #define NS_EVENT_STATE_USERDISABLED  NS_DEFINE_EVENT_STATE_MACRO(15)
     230             : // Content suppressed by the user (ad blocking, etc).
     231             : #define NS_EVENT_STATE_SUPPRESSED    NS_DEFINE_EVENT_STATE_MACRO(16)
     232             : // Content is still loading such that there is nothing to show the
     233             : // user (eg an image which hasn't started coming in yet).
     234             : #define NS_EVENT_STATE_LOADING       NS_DEFINE_EVENT_STATE_MACRO(17)
     235             : // Handler for the content has been blocked.
     236             : #define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(18)
     237             : // Handler for the content has been disabled.
     238             : #define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(19)
     239             : // Handler for the content has crashed
     240             : #define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(20)
     241             : // Content is required.
     242             : #define NS_EVENT_STATE_REQUIRED      NS_DEFINE_EVENT_STATE_MACRO(21)
     243             : // Content is optional (and can be required).
     244             : #define NS_EVENT_STATE_OPTIONAL      NS_DEFINE_EVENT_STATE_MACRO(22)
     245             : // Element is an unresolved custom element candidate
     246             : #define NS_EVENT_STATE_UNRESOLVED NS_DEFINE_EVENT_STATE_MACRO(23)
     247             : // Link has been visited.
     248             : #define NS_EVENT_STATE_VISITED       NS_DEFINE_EVENT_STATE_MACRO(24)
     249             : // Link hasn't been visited.
     250             : #define NS_EVENT_STATE_UNVISITED     NS_DEFINE_EVENT_STATE_MACRO(25)
     251             : // Drag is hovering over content.
     252             : #define NS_EVENT_STATE_DRAGOVER      NS_DEFINE_EVENT_STATE_MACRO(26)
     253             : // Content value is in-range (and can be out-of-range).
     254             : #define NS_EVENT_STATE_INRANGE       NS_DEFINE_EVENT_STATE_MACRO(27)
     255             : // Content value is out-of-range.
     256             : #define NS_EVENT_STATE_OUTOFRANGE    NS_DEFINE_EVENT_STATE_MACRO(28)
     257             : // These two are temporary (see bug 302188)
     258             : // Content is read-only.
     259             : #define NS_EVENT_STATE_MOZ_READONLY  NS_DEFINE_EVENT_STATE_MACRO(29)
     260             : // Content is editable.
     261             : #define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(30)
     262             : // Content is the default one (meaning depends of the context).
     263             : #define NS_EVENT_STATE_DEFAULT       NS_DEFINE_EVENT_STATE_MACRO(31)
     264             : // Content is a submit control and the form isn't valid.
     265             : #define NS_EVENT_STATE_MOZ_SUBMITINVALID NS_DEFINE_EVENT_STATE_MACRO(32)
     266             : // Content is in the optimum region.
     267             : #define NS_EVENT_STATE_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(33)
     268             : // Content is in the suboptimal region.
     269             : #define NS_EVENT_STATE_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(34)
     270             : // Content is in the sub-suboptimal region.
     271             : #define NS_EVENT_STATE_SUB_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(35)
     272             : // Element is highlighted (devtools inspector)
     273             : #define NS_EVENT_STATE_DEVTOOLS_HIGHLIGHTED NS_DEFINE_EVENT_STATE_MACRO(36)
     274             : // Element is transitioning for rules changed by style editor
     275             : #define NS_EVENT_STATE_STYLEEDITOR_TRANSITIONING NS_DEFINE_EVENT_STATE_MACRO(37)
     276             : #define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(38)
     277             : // Content has focus and should show a ring.
     278             : #define NS_EVENT_STATE_FOCUSRING     NS_DEFINE_EVENT_STATE_MACRO(39)
     279             : // Handler for click to play plugin
     280             : #define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(40)
     281             : // Handler for click to play plugin (vulnerable w/update)
     282             : #define NS_EVENT_STATE_VULNERABLE_UPDATABLE NS_DEFINE_EVENT_STATE_MACRO(41)
     283             : // Handler for click to play plugin (vulnerable w/no update)
     284             : #define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(42)
     285             : // Element has focus-within.
     286             : #define NS_EVENT_STATE_FOCUS_WITHIN NS_DEFINE_EVENT_STATE_MACRO(43)
     287             : // Element is ltr (for :dir pseudo-class)
     288             : #define NS_EVENT_STATE_LTR NS_DEFINE_EVENT_STATE_MACRO(44)
     289             : // Element is rtl (for :dir pseudo-class)
     290             : #define NS_EVENT_STATE_RTL NS_DEFINE_EVENT_STATE_MACRO(45)
     291             : // States for tracking the state of the "dir" attribute for HTML elements.  We
     292             : // use these to avoid having to get "dir" attributes all the time during
     293             : // selector matching for some parts of the UA stylesheet.
     294             : //
     295             : // These states are externally managed, because we also don't want to keep
     296             : // getting "dir" attributes in IntrinsicState.
     297             : //
     298             : // Element is HTML and has a "dir" attibute.  This state might go away depending
     299             : // on how https://github.com/whatwg/html/issues/2769 gets resolved.  The value
     300             : // could be anything.
     301             : #define NS_EVENT_STATE_HAS_DIR_ATTR NS_DEFINE_EVENT_STATE_MACRO(46)
     302             : // Element is HTML, has a "dir" attribute, and the attribute's value is
     303             : // case-insensitively equal to "ltr".
     304             : #define NS_EVENT_STATE_DIR_ATTR_LTR NS_DEFINE_EVENT_STATE_MACRO(47)
     305             : // Element is HTML, has a "dir" attribute, and the attribute's value is
     306             : // case-insensitively equal to "rtl".
     307             : #define NS_EVENT_STATE_DIR_ATTR_RTL NS_DEFINE_EVENT_STATE_MACRO(48)
     308             : // Element is HTML, and is either a <bdi> element with no valid-valued "dir"
     309             : // attribute or any HTML element which has a "dir" attribute whose value is
     310             : // "auto".
     311             : #define NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO NS_DEFINE_EVENT_STATE_MACRO(49)
     312             : // Element is filled by Autofill feature.
     313             : #define NS_EVENT_STATE_AUTOFILL NS_DEFINE_EVENT_STATE_MACRO(50)
     314             : // Element is filled with preview data by Autofill feature.
     315             : #define NS_EVENT_STATE_AUTOFILL_PREVIEW NS_DEFINE_EVENT_STATE_MACRO(51)
     316             : 
     317             : // Event state that is used for values that need to be parsed but do nothing.
     318             : #define NS_EVENT_STATE_IGNORE NS_DEFINE_EVENT_STATE_MACRO(63)
     319             : 
     320             : /**
     321             :  * NOTE: do not go over 63 without updating EventStates::InternalType!
     322             :  */
     323             : 
     324             : #define DIRECTION_STATES (NS_EVENT_STATE_LTR | NS_EVENT_STATE_RTL)
     325             : 
     326             : #define DIR_ATTR_STATES (NS_EVENT_STATE_HAS_DIR_ATTR |          \
     327             :                          NS_EVENT_STATE_DIR_ATTR_LTR |          \
     328             :                          NS_EVENT_STATE_DIR_ATTR_RTL |          \
     329             :                          NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO)
     330             : 
     331             : // Event states that can be added and removed through
     332             : // Element::{Add,Remove}ManuallyManagedStates.
     333             : //
     334             : // Take care when manually managing state bits.  You are responsible for
     335             : // setting or clearing the bit when an Element is added or removed from a
     336             : // document (e.g. in BindToTree and UnbindFromTree), if that is an
     337             : // appropriate thing to do for your state bit.
     338             : #define MANUALLY_MANAGED_STATES (             \
     339             :   NS_EVENT_STATE_AUTOFILL |                   \
     340             :   NS_EVENT_STATE_AUTOFILL_PREVIEW             \
     341             : )
     342             : 
     343             : // Event states that are managed externally to an element (by the
     344             : // EventStateManager, or by other code).  As opposed to those in
     345             : // INTRINSIC_STATES, which are are computed by the element itself
     346             : // and returned from Element::IntrinsicState.
     347             : #define EXTERNALLY_MANAGED_STATES (           \
     348             :   MANUALLY_MANAGED_STATES |                   \
     349             :   DIR_ATTR_STATES |                           \
     350             :   NS_EVENT_STATE_ACTIVE |                     \
     351             :   NS_EVENT_STATE_DRAGOVER |                   \
     352             :   NS_EVENT_STATE_FOCUS |                      \
     353             :   NS_EVENT_STATE_FOCUSRING |                  \
     354             :   NS_EVENT_STATE_FOCUS_WITHIN |               \
     355             :   NS_EVENT_STATE_FULL_SCREEN |                \
     356             :   NS_EVENT_STATE_HOVER |                      \
     357             :   NS_EVENT_STATE_UNRESOLVED |                 \
     358             :   NS_EVENT_STATE_URLTARGET                    \
     359             : )
     360             : 
     361             : #define INTRINSIC_STATES (~EXTERNALLY_MANAGED_STATES)
     362             : 
     363             : #endif // mozilla_EventStates_h_

Generated by: LCOV version 1.13