Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/style/nsCSSPseudoElements.cpp
Line
Count
Source (jump to first uncovered line)
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
/* atom list for CSS pseudo-elements */
8
9
#include "nsCSSPseudoElements.h"
10
11
#include "mozilla/ArrayUtils.h"
12
13
#include "nsCSSAnonBoxes.h"
14
#include "nsDOMString.h"
15
#include "nsGkAtomConsts.h"
16
#include "nsStaticAtomUtils.h"
17
18
using namespace mozilla;
19
20
// Flags data for each of the pseudo-elements.
21
/* static */ const uint32_t
22
nsCSSPseudoElements::kPseudoElementFlags[] = {
23
#define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
24
  flags_,
25
#include "nsCSSPseudoElementList.h"
26
#undef CSS_PSEUDO_ELEMENT
27
};
28
29
static nsStaticAtom*
30
GetAtomBase()
31
0
{
32
0
  return const_cast<nsStaticAtom*>(
33
0
      nsGkAtoms::GetAtomByIndex(kAtomIndex_PseudoElements));
34
0
}
35
36
bool
37
nsCSSPseudoElements::IsPseudoElement(nsAtom* aAtom)
38
0
{
39
0
  return nsStaticAtomUtils::IsMember(aAtom, GetAtomBase(),
40
0
                                     kAtomCount_PseudoElements);
41
0
}
42
43
/* static */ bool
44
nsCSSPseudoElements::IsCSS2PseudoElement(nsAtom *aAtom)
45
0
{
46
0
  // We don't implement this using PseudoElementHasFlags because callers
47
0
  // want to pass things that could be anon boxes.
48
0
  NS_ASSERTION(nsCSSPseudoElements::IsPseudoElement(aAtom) ||
49
0
               nsCSSAnonBoxes::IsAnonBox(aAtom),
50
0
               "must be pseudo element or anon box");
51
0
  bool result = aAtom == nsCSSPseudoElements::after() ||
52
0
                  aAtom == nsCSSPseudoElements::before() ||
53
0
                  aAtom == nsCSSPseudoElements::firstLetter() ||
54
0
                  aAtom == nsCSSPseudoElements::firstLine();
55
0
  NS_ASSERTION(nsCSSAnonBoxes::IsAnonBox(aAtom) ||
56
0
               result == PseudoElementHasFlags(
57
0
                   GetPseudoType(aAtom, EnabledState::eIgnoreEnabledState),
58
0
                   CSS_PSEUDO_ELEMENT_IS_CSS2),
59
0
               "result doesn't match flags");
60
0
  return result;
61
0
}
62
63
/* static */ CSSPseudoElementType
64
nsCSSPseudoElements::GetPseudoType(nsAtom* aAtom, EnabledState aEnabledState)
65
0
{
66
0
  Maybe<uint32_t> index =
67
0
    nsStaticAtomUtils::Lookup(aAtom, GetAtomBase(), kAtomCount_PseudoElements);
68
0
  if (index.isSome()) {
69
0
    auto type = static_cast<Type>(*index);
70
0
    return IsEnabled(type, aEnabledState) ? type : Type::NotPseudo;
71
0
  }
72
0
73
0
  if (nsCSSAnonBoxes::IsAnonBox(aAtom)) {
74
0
#ifdef MOZ_XUL
75
0
    if (nsCSSAnonBoxes::IsTreePseudoElement(aAtom)) {
76
0
      return Type::XULTree;
77
0
    }
78
0
#endif
79
0
80
0
    if (nsCSSAnonBoxes::IsNonInheritingAnonBox(aAtom)) {
81
0
      return Type::NonInheritingAnonBox;
82
0
    }
83
0
84
0
    return Type::InheritingAnonBox;
85
0
  }
86
0
87
0
  return Type::NotPseudo;
88
0
}
89
90
/* static */ nsAtom*
91
nsCSSPseudoElements::GetPseudoAtom(Type aType)
92
0
{
93
0
  MOZ_ASSERT(aType < Type::Count, "Unexpected type");
94
0
  size_t index = kAtomIndex_PseudoElements + static_cast<size_t>(aType);
95
0
  return nsGkAtoms::GetAtomByIndex(index);
96
0
}
97
98
/* static */ already_AddRefed<nsAtom>
99
nsCSSPseudoElements::GetPseudoAtom(const nsAString& aPseudoElement)
100
0
{
101
0
  if (DOMStringIsNull(aPseudoElement) || aPseudoElement.IsEmpty() ||
102
0
      aPseudoElement.First() != char16_t(':')) {
103
0
    return nullptr;
104
0
  }
105
0
106
0
  // deal with two-colon forms of aPseudoElt
107
0
  nsAString::const_iterator start, end;
108
0
  aPseudoElement.BeginReading(start);
109
0
  aPseudoElement.EndReading(end);
110
0
  NS_ASSERTION(start != end, "aPseudoElement is not empty!");
111
0
  ++start;
112
0
  bool haveTwoColons = true;
113
0
  if (start == end || *start != char16_t(':')) {
114
0
    --start;
115
0
    haveTwoColons = false;
116
0
  }
117
0
  RefPtr<nsAtom> pseudo = NS_Atomize(Substring(start, end));
118
0
  MOZ_ASSERT(pseudo);
119
0
120
0
  // There aren't any non-CSS2 pseudo-elements with a single ':'
121
0
  if (!haveTwoColons &&
122
0
      (!IsPseudoElement(pseudo) || !IsCSS2PseudoElement(pseudo))) {
123
0
    // XXXbz I'd really rather we threw an exception or something, but
124
0
    // the DOM spec sucks.
125
0
    return nullptr;
126
0
  }
127
0
128
0
  return pseudo.forget();
129
0
}
130
131
/* static */ bool
132
nsCSSPseudoElements::PseudoElementSupportsUserActionState(const Type aType)
133
0
{
134
0
  return PseudoElementHasFlags(aType,
135
0
                               CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE);
136
0
}
137
138
/* static */ nsString
139
nsCSSPseudoElements::PseudoTypeAsString(Type aPseudoType)
140
0
{
141
0
  switch (aPseudoType) {
142
0
    case CSSPseudoElementType::before:
143
0
      return NS_LITERAL_STRING("::before");
144
0
    case CSSPseudoElementType::after:
145
0
      return NS_LITERAL_STRING("::after");
146
0
    default:
147
0
      MOZ_ASSERT(aPseudoType == CSSPseudoElementType::NotPseudo,
148
0
                 "Unexpected pseudo type");
149
0
      return EmptyString();
150
0
  }
151
0
}
152
153
#ifdef DEBUG
154
/* static */ void
155
nsCSSPseudoElements::AssertAtoms()
156
{
157
  nsStaticAtom* base = GetAtomBase();
158
#define CSS_PSEUDO_ELEMENT(name_, value_, flags_)                    \
159
  {                                                                  \
160
    RefPtr<nsAtom> atom = NS_Atomize(value_);                        \
161
    size_t index = static_cast<size_t>(CSSPseudoElementType::name_); \
162
    MOZ_ASSERT(atom == nsGkAtoms::PseudoElement_##name_,             \
163
               "Static atom for " #name_ " has incorrect value");    \
164
    MOZ_ASSERT(atom == &base[index],                                 \
165
               "Static atom for " #name_ " not at expected index");  \
166
  }
167
#include "nsCSSPseudoElementList.h"
168
#undef CSS_PSEUDO_ELEMENT
169
}
170
#endif