CSSPropertyId.h (3946B)
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_CSSPropertyId_h 8 #define mozilla_CSSPropertyId_h 9 10 #include "NonCustomCSSPropertyId.h" 11 #include "mozilla/Assertions.h" 12 #include "mozilla/HashFunctions.h" 13 #include "mozilla/RefPtr.h" 14 #include "mozilla/ServoBindings.h" 15 #include "nsAtom.h" 16 #include "nsCSSProps.h" 17 #include "nsString.h" 18 19 namespace mozilla { 20 21 struct CSSPropertyId { 22 explicit CSSPropertyId(NonCustomCSSPropertyId aProperty) : mId(aProperty) { 23 MOZ_ASSERT(aProperty != eCSSPropertyExtra_variable, 24 "Cannot create an CSSPropertyId from only a " 25 "eCSSPropertyExtra_variable."); 26 } 27 28 private: 29 explicit CSSPropertyId(RefPtr<nsAtom> aCustomName) 30 : mId(eCSSPropertyExtra_variable), mCustomName(std::move(aCustomName)) { 31 MOZ_ASSERT(mCustomName, "Null custom property name"); 32 } 33 34 public: 35 // Callers are expected to pass a custom name atom with the leading "--" 36 // already stripped. The remaining ident may legally start with "-" 37 // (or even "--"), so we cannot assert anything about its prefix here. 38 static CSSPropertyId FromCustomName(RefPtr<nsAtom> aCustomName) { 39 return CSSPropertyId(aCustomName); 40 } 41 42 static CSSPropertyId FromCustomProperty(const nsACString& aCustomProperty) { 43 MOZ_ASSERT(StringBeginsWith(aCustomProperty, "--"_ns)); 44 45 // TODO(zrhoffman, bug 1811897) Add test coverage for removing the `--` 46 // prefix here. 47 RefPtr<nsAtom> atom = 48 NS_Atomize(Substring(aCustomProperty, 2, aCustomProperty.Length() - 2)); 49 50 return FromCustomName(atom); 51 } 52 53 static CSSPropertyId FromIdOrCustomProperty( 54 NonCustomCSSPropertyId aId, const nsACString& aCustomProperty) { 55 if (aId != eCSSPropertyExtra_variable) { 56 return CSSPropertyId(aId); 57 } 58 59 return FromCustomProperty(aCustomProperty); 60 } 61 62 NonCustomCSSPropertyId mId = eCSSProperty_UNKNOWN; 63 RefPtr<nsAtom> mCustomName; 64 65 bool IsCustom() const { return mId == eCSSPropertyExtra_variable; } 66 67 bool operator==(const CSSPropertyId&) const = default; 68 bool operator!=(const CSSPropertyId&) const = default; 69 70 bool IsValid() const { 71 if (mId == eCSSProperty_UNKNOWN) { 72 return false; 73 } 74 return IsCustom() == !!mCustomName; 75 } 76 77 void ToString(nsACString& aString) const { 78 if (IsCustom()) { 79 MOZ_ASSERT(mCustomName, "Custom property should have a name"); 80 // mCustomName does not include the "--" prefix 81 aString.AssignLiteral("--"); 82 AppendUTF16toUTF8(nsDependentAtomString(mCustomName), aString); 83 } else { 84 aString.Assign(nsCSSProps::GetStringValue(mId)); 85 } 86 } 87 88 void ToString(nsAString& aString) const { 89 if (IsCustom()) { 90 MOZ_ASSERT(mCustomName, "Custom property should have a name"); 91 // mCustomName does not include the "--" prefix 92 aString.AssignLiteral("--"); 93 aString.Append(nsDependentAtomString(mCustomName)); 94 } else { 95 aString.Assign(NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(mId))); 96 } 97 } 98 99 HashNumber Hash() const { 100 HashNumber hash = mCustomName ? mCustomName->hash() : 0; 101 return AddToHash(hash, mId); 102 } 103 104 CSSPropertyId ToPhysical(const ComputedStyle& aStyle) const { 105 if (IsCustom()) { 106 return *this; 107 } 108 return CSSPropertyId{nsCSSProps::Physicalize(mId, aStyle)}; 109 } 110 }; 111 112 // MOZ_DBG support for AnimatedPropertyId 113 inline std::ostream& operator<<(std::ostream& aOut, 114 const CSSPropertyId& aProperty) { 115 if (aProperty.IsCustom()) { 116 return aOut << nsAtomCString(aProperty.mCustomName); 117 } 118 return aOut << nsCSSProps::GetStringValue(aProperty.mId); 119 } 120 121 } // namespace mozilla 122 123 #endif // mozilla_CSSPropertyId_h