/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_CSSPropertyId_h #define mozilla_CSSPropertyId_h #include "NonCustomCSSPropertyId.h" #include "mozilla/Assertions.h" #include "mozilla/HashFunctions.h" #include "mozilla/RefPtr.h" #include "mozilla/ServoBindings.h" #include "nsAtom.h" #include "nsCSSProps.h" #include "nsString.h" namespace mozilla { struct CSSPropertyId { explicit CSSPropertyId(NonCustomCSSPropertyId aProperty) : mId(aProperty) { MOZ_ASSERT(aProperty != eCSSPropertyExtra_variable, "Cannot create an CSSPropertyId from only a " "eCSSPropertyExtra_variable."); } private: explicit CSSPropertyId(RefPtr aCustomName) : mId(eCSSPropertyExtra_variable), mCustomName(std::move(aCustomName)) { MOZ_ASSERT(mCustomName, "Null custom property name"); } public: // Callers are expected to pass a custom name atom with the leading "--" // already stripped. The remaining ident may legally start with "-" // (or even "--"), so we cannot assert anything about its prefix here. static CSSPropertyId FromCustomName(RefPtr aCustomName) { return CSSPropertyId(aCustomName); } static CSSPropertyId FromCustomProperty(const nsACString& aCustomProperty) { MOZ_ASSERT(StringBeginsWith(aCustomProperty, "--"_ns)); // TODO(zrhoffman, bug 1811897) Add test coverage for removing the `--` // prefix here. RefPtr atom = NS_Atomize(Substring(aCustomProperty, 2, aCustomProperty.Length() - 2)); return FromCustomName(atom); } static CSSPropertyId FromIdOrCustomProperty( NonCustomCSSPropertyId aId, const nsACString& aCustomProperty) { if (aId != eCSSPropertyExtra_variable) { return CSSPropertyId(aId); } return FromCustomProperty(aCustomProperty); } NonCustomCSSPropertyId mId = eCSSProperty_UNKNOWN; RefPtr mCustomName; bool IsCustom() const { return mId == eCSSPropertyExtra_variable; } bool operator==(const CSSPropertyId& aOther) const { return mId == aOther.mId && mCustomName == aOther.mCustomName; } bool operator!=(const CSSPropertyId& aOther) const { return !(*this == aOther); } bool IsValid() const { if (mId == eCSSProperty_UNKNOWN) { return false; } return IsCustom() == !!mCustomName; } void ToString(nsACString& aString) const { if (IsCustom()) { MOZ_ASSERT(mCustomName, "Custom property should have a name"); // mCustomName does not include the "--" prefix aString.AssignLiteral("--"); AppendUTF16toUTF8(nsDependentAtomString(mCustomName), aString); } else { aString.Assign(nsCSSProps::GetStringValue(mId)); } } void ToString(nsAString& aString) const { if (IsCustom()) { MOZ_ASSERT(mCustomName, "Custom property should have a name"); // mCustomName does not include the "--" prefix aString.AssignLiteral("--"); aString.Append(nsDependentAtomString(mCustomName)); } else { aString.Assign(NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(mId))); } } HashNumber Hash() const { HashNumber hash = mCustomName ? mCustomName->hash() : 0; return AddToHash(hash, mId); } CSSPropertyId ToPhysical(const ComputedStyle& aStyle) const { if (IsCustom()) { return *this; } return CSSPropertyId{nsCSSProps::Physicalize(mId, aStyle)}; } }; // MOZ_DBG support for AnimatedPropertyId inline std::ostream& operator<<(std::ostream& aOut, const CSSPropertyId& aProperty) { if (aProperty.IsCustom()) { return aOut << nsAtomCString(aProperty.mCustomName); } return aOut << nsCSSProps::GetStringValue(aProperty.mId); } } // namespace mozilla #endif // mozilla_CSSPropertyId_h