From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- accessible/base/AccAttributes.h | 294 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 accessible/base/AccAttributes.h (limited to 'accessible/base/AccAttributes.h') diff --git a/accessible/base/AccAttributes.h b/accessible/base/AccAttributes.h new file mode 100644 index 0000000000..6ee78aaaa0 --- /dev/null +++ b/accessible/base/AccAttributes.h @@ -0,0 +1,294 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 AccAttributes_h_ +#define AccAttributes_h_ + +#include "mozilla/ServoStyleConsts.h" +#include "mozilla/a11y/AccGroupInfo.h" +#include "mozilla/Variant.h" +#include "nsTHashMap.h" +#include "nsAtom.h" +#include "nsStringFwd.h" +#include "mozilla/gfx/Matrix.h" + +class nsVariant; + +namespace IPC { +template +struct ParamTraits; +} // namespace IPC + +namespace mozilla { + +namespace dom { +class Element; +} + +namespace a11y { + +struct FontSize { + int32_t mValue; + + bool operator==(const FontSize& aOther) const { + return mValue == aOther.mValue; + } + + bool operator!=(const FontSize& aOther) const { + return mValue != aOther.mValue; + } +}; + +struct Color { + nscolor mValue; + + bool operator==(const Color& aOther) const { return mValue == aOther.mValue; } + + bool operator!=(const Color& aOther) const { return mValue != aOther.mValue; } +}; + +// A special type. If an entry has a value of this type, it instructs the +// target instance of an Update to remove the entry with the same key value. +struct DeleteEntry { + DeleteEntry() : mValue(true) {} + bool mValue; + + bool operator==(const DeleteEntry& aOther) const { return true; } + + bool operator!=(const DeleteEntry& aOther) const { return false; } +}; + +class AccAttributes { + // Warning! An AccAttributes can contain another AccAttributes. This is + // intended for object and text attributes. However, the nested + // AccAttributes should never itself contain another AccAttributes, nor + // should it create a cycle. We don't do cycle collection here for + // performance reasons, so violating this rule will cause leaks! + using AttrValueType = + Variant, nsTArray, + CSSCoord, FontSize, Color, DeleteEntry, UniquePtr, + RefPtr, uint64_t, UniquePtr, + UniquePtr, nsTArray>; + static_assert(sizeof(AttrValueType) <= 16); + using AtomVariantMap = nsTHashMap, AttrValueType>; + + protected: + ~AccAttributes() = default; + + public: + AccAttributes() = default; + AccAttributes(const AccAttributes&) = delete; + AccAttributes& operator=(const AccAttributes&) = delete; + + NS_INLINE_DECL_REFCOUNTING(mozilla::a11y::AccAttributes) + + template + void SetAttribute(nsAtom* aAttrName, T&& aAttrValue) { + using ValType = + std::remove_const_t>; + if constexpr (std::is_convertible_v) { + static_assert(std::is_rvalue_reference_v, + "Please only move strings into this function. To make a " + "copy, use SetAttributeStringCopy."); + UniquePtr value = MakeUnique(std::move(aAttrValue)); + mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value))); + } else if constexpr (std::is_same_v) { + UniquePtr value = MakeUnique(aAttrValue); + mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value))); + } else if constexpr (std::is_same_v) { + UniquePtr value(aAttrValue); + mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value))); + } else if constexpr (std::is_convertible_v) { + mData.InsertOrUpdate(aAttrName, AsVariant(RefPtr(aAttrValue))); + } else { + mData.InsertOrUpdate(aAttrName, AsVariant(std::forward(aAttrValue))); + } + } + + void SetAttributeStringCopy(nsAtom* aAttrName, nsString aAttrValue) { + SetAttribute(aAttrName, std::move(aAttrValue)); + } + + template + Maybe GetAttribute(nsAtom* aAttrName) const { + if (auto value = mData.Lookup(aAttrName)) { + if constexpr (std::is_same_v) { + if (value->is>()) { + const T& val = *(value->as>().get()); + return SomeRef(val); + } + } else if constexpr (std::is_same_v) { + if (value->is>()) { + const T& val = *(value->as>()); + return SomeRef(val); + } + } else { + if (value->is()) { + const T& val = value->as(); + return SomeRef(val); + } + } + } + return Nothing(); + } + + template + RefPtr GetAttributeRefPtr(nsAtom* aAttrName) const { + if (auto value = mData.Lookup(aAttrName)) { + if (value->is>()) { + RefPtr ref = value->as>(); + return ref; + } + } + return nullptr; + } + + template + Maybe GetMutableAttribute(nsAtom* aAttrName) const { + static_assert(std::is_same_v, T> || + std::is_same_v, T>, + "Only arrays should be mutable attributes"); + if (auto value = mData.Lookup(aAttrName)) { + if (value->is()) { + T& val = value->as(); + return SomeRef(val); + } + } + return Nothing(); + } + + // Get stringified value + bool GetAttribute(nsAtom* aAttrName, nsAString& aAttrValue) const; + + bool HasAttribute(nsAtom* aAttrName) const { + return mData.Contains(aAttrName); + } + + bool Remove(nsAtom* aAttrName) { return mData.Remove(aAttrName); } + + uint32_t Count() const { return mData.Count(); } + + // Update one instance with the entries in another. The supplied AccAttributes + // will be emptied. + void Update(AccAttributes* aOther); + + /** + * Return true if all the attributes in this instance are equal to all the + * attributes in another instance. + */ + bool Equal(const AccAttributes* aOther) const; + + /** + * Copy attributes from this instance to another instance. + * This should only be used in very specific cases; e.g. merging two sets of + * cached attributes without modifying the cache. It can only copy simple + * value types; e.g. it can't copy array values. Attempting to copy an + * AccAttributes with uncopyable values will cause an assertion. + */ + void CopyTo(AccAttributes* aDest) const; + + // An entry class for our iterator. + class Entry { + public: + Entry(nsAtom* aAttrName, const AttrValueType* aAttrValue) + : mName(aAttrName), mValue(aAttrValue) {} + + nsAtom* Name() const { return mName; } + + template + Maybe Value() const { + if constexpr (std::is_same_v) { + if (mValue->is>()) { + const T& val = *(mValue->as>().get()); + return SomeRef(val); + } + } else if constexpr (std::is_same_v) { + if (mValue->is>()) { + const T& val = *(mValue->as>()); + return SomeRef(val); + } + } else { + if (mValue->is()) { + const T& val = mValue->as(); + return SomeRef(val); + } + } + return Nothing(); + } + + void NameAsString(nsString& aName) const { + mName->ToString(aName); + if (StringBeginsWith(aName, u"aria-"_ns)) { + // Found 'aria-' + aName.ReplaceLiteral(0, 5, u""); + } + } + + void ValueAsString(nsAString& aValueString) const { + StringFromValueAndName(mName, *mValue, aValueString); + } + + // Size of the pair in the hash table. + size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf); + + private: + nsAtom* mName; + const AttrValueType* mValue; + + friend class AccAttributes; + }; + + class Iterator { + public: + explicit Iterator(AtomVariantMap::const_iterator aIter) + : mHashIterator(aIter) {} + + Iterator() = delete; + Iterator(const Iterator&) = delete; + Iterator& operator=(const Iterator&) = delete; + + bool operator!=(const Iterator& aOther) const { + return mHashIterator != aOther.mHashIterator; + } + + Iterator& operator++() { + mHashIterator++; + return *this; + } + + Entry operator*() const { + auto& entry = *mHashIterator; + return Entry(entry.GetKey(), &entry.GetData()); + } + + private: + AtomVariantMap::const_iterator mHashIterator; + }; + + friend class Iterator; + + Iterator begin() const { return Iterator(mData.begin()); } + Iterator end() const { return Iterator(mData.end()); } + +#ifdef A11Y_LOG + static void DebugPrint(const char* aPrefix, const AccAttributes& aAttributes); +#endif + + size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf); + + private: + static void StringFromValueAndName(nsAtom* aAttrName, + const AttrValueType& aValue, + nsAString& aValueString); + + AtomVariantMap mData; + + friend struct IPC::ParamTraits; +}; + +} // namespace a11y +} // namespace mozilla + +#endif -- cgit v1.2.3