MappedDeclarationsBuilder.h (7199B)
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 /* Representation of a declaration block used for attribute mapping */ 8 9 #ifndef mozilla_MappedDeclarationsBuilder_h 10 #define mozilla_MappedDeclarationsBuilder_h 11 12 #include "NonCustomCSSPropertyId.h" 13 #include "mozilla/FontPropertyTypes.h" 14 #include "mozilla/ServoBindingTypes.h" 15 #include "mozilla/ServoBindings.h" 16 #include "mozilla/dom/Element.h" 17 #include "nsCSSValue.h" 18 #include "nsColor.h" 19 20 class nsAttrValue; 21 22 namespace mozilla { 23 24 // This provides a convenient interface for attribute mappers 25 // (MapAttributesIntoRule) to modify the presentation attribute declaration 26 // block for a given element. 27 class MOZ_STACK_CLASS MappedDeclarationsBuilder final { 28 public: 29 explicit MappedDeclarationsBuilder( 30 dom::Element& aElement, dom::Document& aDoc, 31 StyleLockedDeclarationBlock* aDecls = nullptr) 32 : mDocument(aDoc), mElement(aElement), mDecls(aDecls) { 33 if (mDecls) { 34 Servo_DeclarationBlock_Clear(mDecls); 35 } 36 } 37 38 ~MappedDeclarationsBuilder() { 39 MOZ_ASSERT(!mDecls, "Forgot to take the block?"); 40 } 41 42 dom::Document& Document() { return mDocument; } 43 44 already_AddRefed<StyleLockedDeclarationBlock> TakeDeclarationBlock() { 45 return mDecls.forget(); 46 } 47 48 // Check if we already contain a certain longhand 49 bool PropertyIsSet(NonCustomCSSPropertyId aId) const { 50 return mDecls && Servo_DeclarationBlock_PropertyIsSet(mDecls, aId); 51 } 52 53 // Set a property to an identifier (string) 54 void SetIdentStringValue(NonCustomCSSPropertyId aId, const nsString& aValue) { 55 RefPtr<nsAtom> atom = NS_AtomizeMainThread(aValue); 56 SetIdentAtomValue(aId, atom); 57 } 58 59 void SetIdentStringValueIfUnset(NonCustomCSSPropertyId aId, 60 const nsString& aValue) { 61 if (!PropertyIsSet(aId)) { 62 SetIdentStringValue(aId, aValue); 63 } 64 } 65 66 void SetIdentAtomValue(NonCustomCSSPropertyId aId, nsAtom* aValue); 67 68 void SetIdentAtomValueIfUnset(NonCustomCSSPropertyId aId, nsAtom* aValue) { 69 if (!PropertyIsSet(aId)) { 70 SetIdentAtomValue(aId, aValue); 71 } 72 } 73 74 // Set a property to a keyword (usually NS_STYLE_* or StyleFoo::*) 75 void SetKeywordValue(NonCustomCSSPropertyId aId, int32_t aValue) { 76 Servo_DeclarationBlock_SetKeywordValue(&EnsureDecls(), aId, aValue); 77 } 78 79 void SetKeywordValueIfUnset(NonCustomCSSPropertyId aId, int32_t aValue) { 80 if (!PropertyIsSet(aId)) { 81 SetKeywordValue(aId, aValue); 82 } 83 } 84 85 template <typename T, 86 typename = typename std::enable_if<std::is_enum<T>::value>::type> 87 void SetKeywordValue(NonCustomCSSPropertyId aId, T aValue) { 88 static_assert(EnumTypeFitsWithin<T, int32_t>::value, 89 "aValue must be an enum that fits within 32 bits"); 90 SetKeywordValue(aId, static_cast<int32_t>(aValue)); 91 } 92 template <typename T, 93 typename = typename std::enable_if<std::is_enum<T>::value>::type> 94 void SetKeywordValueIfUnset(NonCustomCSSPropertyId aId, T aValue) { 95 static_assert(EnumTypeFitsWithin<T, int32_t>::value, 96 "aValue must be an enum that fits within 32 bits"); 97 SetKeywordValueIfUnset(aId, static_cast<int32_t>(aValue)); 98 } 99 100 // Set a property to an integer value 101 void SetIntValue(NonCustomCSSPropertyId aId, int32_t aValue) { 102 Servo_DeclarationBlock_SetIntValue(&EnsureDecls(), aId, aValue); 103 } 104 105 // Set "math-depth: <integer>" or "math-depth: add(<integer>)" 106 void SetMathDepthValue(int32_t aValue, bool aIsRelative) { 107 Servo_DeclarationBlock_SetMathDepthValue(&EnsureDecls(), aValue, 108 aIsRelative); 109 } 110 111 // Set "counter-reset: list-item <integer>". If aIsReversed is true then 112 // "list-item" instead becomes "reversed(list-item)". 113 void SetCounterResetListItem(int32_t aValue, bool aIsReversed) { 114 Servo_DeclarationBlock_SetCounterResetListItem(&EnsureDecls(), aValue, 115 aIsReversed); 116 } 117 118 // Set "counter-set: list-item <integer>". 119 void SetCounterSetListItem(int32_t aValue) { 120 Servo_DeclarationBlock_SetCounterSetListItem(&EnsureDecls(), aValue); 121 } 122 123 // Set a property to a pixel value 124 void SetPixelValue(NonCustomCSSPropertyId aId, float aValue) { 125 Servo_DeclarationBlock_SetPixelValue(&EnsureDecls(), aId, aValue); 126 } 127 128 void SetPixelValueIfUnset(NonCustomCSSPropertyId aId, float aValue) { 129 if (!PropertyIsSet(aId)) { 130 SetPixelValue(aId, aValue); 131 } 132 } 133 134 void SetLengthValue(NonCustomCSSPropertyId aId, const nsCSSValue& aValue) { 135 MOZ_ASSERT(aValue.IsLengthUnit()); 136 Servo_DeclarationBlock_SetLengthValue( 137 &EnsureDecls(), aId, aValue.GetFloatValue(), aValue.GetUnit()); 138 } 139 140 // Set a property to a percent value 141 void SetPercentValue(NonCustomCSSPropertyId aId, float aValue) { 142 Servo_DeclarationBlock_SetPercentValue(&EnsureDecls(), aId, aValue); 143 } 144 145 void SetPercentValueIfUnset(NonCustomCSSPropertyId aId, float aValue) { 146 if (!PropertyIsSet(aId)) { 147 SetPercentValue(aId, aValue); 148 } 149 } 150 151 // Set a property to `auto` 152 void SetAutoValue(NonCustomCSSPropertyId aId) { 153 Servo_DeclarationBlock_SetAutoValue(&EnsureDecls(), aId); 154 } 155 156 void SetAutoValueIfUnset(NonCustomCSSPropertyId aId) { 157 if (!PropertyIsSet(aId)) { 158 SetAutoValue(aId); 159 } 160 } 161 162 // Set a property to `currentcolor` 163 void SetCurrentColor(NonCustomCSSPropertyId aId) { 164 Servo_DeclarationBlock_SetCurrentColor(&EnsureDecls(), aId); 165 } 166 167 void SetCurrentColorIfUnset(NonCustomCSSPropertyId aId) { 168 if (!PropertyIsSet(aId)) { 169 SetCurrentColor(aId); 170 } 171 } 172 173 // Set a property to an RGBA nscolor value 174 void SetColorValue(NonCustomCSSPropertyId aId, nscolor aValue) { 175 Servo_DeclarationBlock_SetColorValue(&EnsureDecls(), aId, aValue); 176 } 177 178 void SetColorValueIfUnset(NonCustomCSSPropertyId aId, nscolor aValue) { 179 if (!PropertyIsSet(aId)) { 180 SetColorValue(aId, aValue); 181 } 182 } 183 184 // Set font-family to a string 185 void SetFontFamily(const nsACString& aValue) { 186 Servo_DeclarationBlock_SetFontFamily(&EnsureDecls(), &aValue); 187 } 188 189 // Add a quirks-mode override to the decoration color of elements nested in 190 // <a> 191 void SetTextDecorationColorOverride() { 192 Servo_DeclarationBlock_SetTextDecorationColorOverride(&EnsureDecls()); 193 } 194 195 void SetBackgroundImage(const nsAttrValue& value); 196 197 void SetAspectRatio(float aWidth, float aHeight) { 198 Servo_DeclarationBlock_SetAspectRatio(&EnsureDecls(), aWidth, aHeight); 199 } 200 201 const nsAttrValue* GetAttr(nsAtom* aName) { 202 MOZ_ASSERT(mElement.IsAttributeMapped(aName)); 203 return mElement.GetParsedAttr(aName); 204 } 205 206 private: 207 StyleLockedDeclarationBlock& EnsureDecls() { 208 if (!mDecls) { 209 mDecls = Servo_DeclarationBlock_CreateEmpty().Consume(); 210 } 211 return *mDecls; 212 } 213 214 dom::Document& mDocument; 215 dom::Element& mElement; 216 RefPtr<StyleLockedDeclarationBlock> mDecls; 217 }; 218 219 } // namespace mozilla 220 221 #endif