зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1839223
- Remove nsMappedAttributes. r=smaug
Instead, lazily schedule evaluation of them before styling, much like we were doing for SVG. A subtle tweak is that we only remain scheduled while in the document. This allows us to use the "in document" bit plus the "mapped attributes dirty" bit to know our scheduled status. It also prevents doing silly work for disconnected elements, and having to do hashmap lookups on adoption and node destruction. Differential Revision: https://phabricator.services.mozilla.com/D181549
This commit is contained in:
Родитель
4bba5ff713
Коммит
7bddcf9e5a
|
@ -15,40 +15,47 @@
|
|||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/ServoBindings.h"
|
||||
|
||||
#include "nsMappedAttributeElement.h"
|
||||
#include "nsString.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsContentUtils.h" // nsAutoScriptBlocker
|
||||
|
||||
using mozilla::CheckedUint32;
|
||||
using mozilla::dom::Document;
|
||||
|
||||
AttrArray::Impl::~Impl() {
|
||||
for (InternalAttr& attr : NonMappedAttrs()) {
|
||||
for (InternalAttr& attr : Attrs()) {
|
||||
attr.~InternalAttr();
|
||||
}
|
||||
if (auto* decl = GetMappedDeclarationBlock()) {
|
||||
Servo_DeclarationBlock_Release(decl);
|
||||
mMappedAttributeBits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mMappedAttrs);
|
||||
void AttrArray::SetMappedDeclarationBlock(
|
||||
already_AddRefed<mozilla::StyleLockedDeclarationBlock> aBlock) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mImpl);
|
||||
MOZ_ASSERT(IsPendingMappedAttributeEvaluation());
|
||||
if (auto* decl = GetMappedDeclarationBlock()) {
|
||||
Servo_DeclarationBlock_Release(decl);
|
||||
}
|
||||
mImpl->mMappedAttributeBits = reinterpret_cast<uintptr_t>(aBlock.take());
|
||||
MOZ_ASSERT(!IsPendingMappedAttributeEvaluation());
|
||||
}
|
||||
|
||||
const nsAttrValue* AttrArray::GetAttr(const nsAtom* aLocalName,
|
||||
int32_t aNamespaceID) const {
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
// This should be the common case so lets make an optimized loop
|
||||
for (const InternalAttr& attr : NonMappedAttrs()) {
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.Equals(aLocalName)) {
|
||||
return &attr.mValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (mImpl && mImpl->mMappedAttrs) {
|
||||
return mImpl->mMappedAttrs->GetAttr(aLocalName);
|
||||
}
|
||||
} else {
|
||||
for (const InternalAttr& attr : NonMappedAttrs()) {
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.Equals(aLocalName, aNamespaceID)) {
|
||||
return &attr.mValue;
|
||||
}
|
||||
|
@ -59,16 +66,11 @@ const nsAttrValue* AttrArray::GetAttr(const nsAtom* aLocalName,
|
|||
}
|
||||
|
||||
const nsAttrValue* AttrArray::GetAttr(const nsAString& aLocalName) const {
|
||||
for (const InternalAttr& attr : NonMappedAttrs()) {
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.Equals(aLocalName)) {
|
||||
return &attr.mValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (mImpl && mImpl->mMappedAttrs) {
|
||||
return mImpl->mMappedAttrs->GetAttr(aLocalName);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -85,28 +87,18 @@ const nsAttrValue* AttrArray::GetAttr(const nsAString& aName,
|
|||
return GetAttr(lowercase, eCaseMatters);
|
||||
}
|
||||
|
||||
for (const InternalAttr& attr : NonMappedAttrs()) {
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.QualifiedNameEquals(aName)) {
|
||||
return &attr.mValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (mImpl && mImpl->mMappedAttrs) {
|
||||
return mImpl->mMappedAttrs->GetAttr(aName);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const nsAttrValue* AttrArray::AttrAt(uint32_t aPos) const {
|
||||
NS_ASSERTION(aPos < AttrCount(), "out-of-bounds access in AttrArray");
|
||||
|
||||
uint32_t nonmapped = NonMappedAttrCount();
|
||||
if (aPos < nonmapped) {
|
||||
return &mImpl->NonMappedAttrs()[aPos].mValue;
|
||||
}
|
||||
|
||||
return mImpl->mMappedAttrs->AttrAt(aPos - nonmapped);
|
||||
return &mImpl->Attrs()[aPos].mValue;
|
||||
}
|
||||
|
||||
template <typename Name>
|
||||
|
@ -129,7 +121,7 @@ nsresult AttrArray::SetAndSwapAttr(nsAtom* aLocalName, nsAttrValue& aValue,
|
|||
bool* aHadValue) {
|
||||
*aHadValue = false;
|
||||
|
||||
for (InternalAttr& attr : NonMappedAttrs()) {
|
||||
for (InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.Equals(aLocalName)) {
|
||||
attr.mValue.SwapValueWith(aValue);
|
||||
*aHadValue = true;
|
||||
|
@ -149,7 +141,7 @@ nsresult AttrArray::SetAndSwapAttr(mozilla::dom::NodeInfo* aName,
|
|||
}
|
||||
|
||||
*aHadValue = false;
|
||||
for (InternalAttr& attr : NonMappedAttrs()) {
|
||||
for (InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.Equals(localName, namespaceID)) {
|
||||
attr.mName.SetTo(aName);
|
||||
attr.mValue.SwapValueWith(aValue);
|
||||
|
@ -164,82 +156,41 @@ nsresult AttrArray::SetAndSwapAttr(mozilla::dom::NodeInfo* aName,
|
|||
nsresult AttrArray::RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue) {
|
||||
NS_ASSERTION(aPos < AttrCount(), "out-of-bounds");
|
||||
|
||||
uint32_t nonmapped = NonMappedAttrCount();
|
||||
if (aPos < nonmapped) {
|
||||
mImpl->mBuffer[aPos].mValue.SwapValueWith(aValue);
|
||||
mImpl->mBuffer[aPos].~InternalAttr();
|
||||
mImpl->mBuffer[aPos].mValue.SwapValueWith(aValue);
|
||||
mImpl->mBuffer[aPos].~InternalAttr();
|
||||
|
||||
memmove(mImpl->mBuffer + aPos, mImpl->mBuffer + aPos + 1,
|
||||
(mImpl->mAttrCount - aPos - 1) * sizeof(InternalAttr));
|
||||
memmove(mImpl->mBuffer + aPos, mImpl->mBuffer + aPos + 1,
|
||||
(mImpl->mAttrCount - aPos - 1) * sizeof(InternalAttr));
|
||||
|
||||
--mImpl->mAttrCount;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (MappedAttrCount() == 1) {
|
||||
// We're removing the last mapped attribute. Can't swap in this
|
||||
// case; have to copy.
|
||||
aValue.SetTo(*mImpl->mMappedAttrs->AttrAt(0));
|
||||
NS_RELEASE(mImpl->mMappedAttrs);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<nsMappedAttributes> mapped = ModifiableMapped(nullptr, false);
|
||||
mapped->RemoveAttrAt(aPos - nonmapped, aValue);
|
||||
return MakeMappedUnique(mapped);
|
||||
--mImpl->mAttrCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mozilla::dom::BorrowedAttrInfo AttrArray::AttrInfoAt(uint32_t aPos) const {
|
||||
NS_ASSERTION(aPos < AttrCount(), "out-of-bounds access in AttrArray");
|
||||
|
||||
uint32_t nonmapped = NonMappedAttrCount();
|
||||
if (aPos < nonmapped) {
|
||||
InternalAttr& attr = mImpl->mBuffer[aPos];
|
||||
return BorrowedAttrInfo(&attr.mName, &attr.mValue);
|
||||
}
|
||||
|
||||
return BorrowedAttrInfo(mImpl->mMappedAttrs->NameAt(aPos - nonmapped),
|
||||
mImpl->mMappedAttrs->AttrAt(aPos - nonmapped));
|
||||
InternalAttr& attr = mImpl->mBuffer[aPos];
|
||||
return BorrowedAttrInfo(&attr.mName, &attr.mValue);
|
||||
}
|
||||
|
||||
const nsAttrName* AttrArray::AttrNameAt(uint32_t aPos) const {
|
||||
NS_ASSERTION(aPos < AttrCount(), "out-of-bounds access in AttrArray");
|
||||
|
||||
uint32_t nonmapped = NonMappedAttrCount();
|
||||
if (aPos < nonmapped) {
|
||||
return &mImpl->mBuffer[aPos].mName;
|
||||
}
|
||||
|
||||
return mImpl->mMappedAttrs->NameAt(aPos - nonmapped);
|
||||
return &mImpl->mBuffer[aPos].mName;
|
||||
}
|
||||
|
||||
const nsAttrName* AttrArray::GetSafeAttrNameAt(uint32_t aPos) const {
|
||||
uint32_t nonmapped = NonMappedAttrCount();
|
||||
if (aPos < nonmapped) {
|
||||
return &mImpl->mBuffer[aPos].mName;
|
||||
}
|
||||
|
||||
if (aPos >= AttrCount()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mImpl->mMappedAttrs->NameAt(aPos - nonmapped);
|
||||
return &mImpl->mBuffer[aPos].mName;
|
||||
}
|
||||
|
||||
const nsAttrName* AttrArray::GetExistingAttrNameFromQName(
|
||||
const nsAString& aName) const {
|
||||
for (const InternalAttr& attr : NonMappedAttrs()) {
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.QualifiedNameEquals(aName)) {
|
||||
return &attr.mName;
|
||||
}
|
||||
}
|
||||
|
||||
if (mImpl && mImpl->mMappedAttrs) {
|
||||
return mImpl->mMappedAttrs->GetExistingAttrNameFromQName(aName);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -249,14 +200,6 @@ int32_t AttrArray::IndexOfAttr(const nsAtom* aLocalName,
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t idx;
|
||||
if (mImpl->mMappedAttrs && aNamespaceID == kNameSpaceID_None) {
|
||||
idx = mImpl->mMappedAttrs->IndexOfAttr(aLocalName);
|
||||
if (idx >= 0) {
|
||||
return NonMappedAttrCount() + idx;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t i = 0;
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
// This should be the common case so lets make an optimized loop
|
||||
|
@ -265,14 +208,14 @@ int32_t AttrArray::IndexOfAttr(const nsAtom* aLocalName,
|
|||
// against null would fail in the loop body (since Equals() just compares
|
||||
// the raw pointer value of aLocalName to what AttrSlotIsTaken() would be
|
||||
// checking.
|
||||
for (const InternalAttr& attr : NonMappedAttrs()) {
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.Equals(aLocalName)) {
|
||||
return i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
for (const InternalAttr& attr : NonMappedAttrs()) {
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.Equals(aLocalName, aNamespaceID)) {
|
||||
return i;
|
||||
}
|
||||
|
@ -283,53 +226,12 @@ int32_t AttrArray::IndexOfAttr(const nsAtom* aLocalName,
|
|||
return -1;
|
||||
}
|
||||
|
||||
nsresult AttrArray::SetAndSwapMappedAttr(nsAtom* aLocalName,
|
||||
nsAttrValue& aValue,
|
||||
nsMappedAttributeElement* aContent,
|
||||
bool* aHadValue) {
|
||||
bool willAdd = true;
|
||||
if (mImpl && mImpl->mMappedAttrs) {
|
||||
willAdd = !mImpl->mMappedAttrs->GetAttr(aLocalName);
|
||||
}
|
||||
|
||||
RefPtr<nsMappedAttributes> mapped = ModifiableMapped(aContent, willAdd);
|
||||
|
||||
mapped->SetAndSwapAttr(aLocalName, aValue, aHadValue);
|
||||
|
||||
return MakeMappedUnique(mapped);
|
||||
}
|
||||
|
||||
nsresult AttrArray::SetMappedAttributeStyles(
|
||||
mozilla::AttributeStyles* aNewStyles) {
|
||||
MOZ_ASSERT(mImpl && mImpl->mMappedAttrs, "Should have mapped attrs here!");
|
||||
if (aNewStyles == mImpl->mMappedAttrs->GetAttributeStyles()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<nsMappedAttributes> mapped = ModifiableMapped(nullptr, false);
|
||||
mapped->DropAttributeStylesReference();
|
||||
mapped->SetAttributeStyles(aNewStyles);
|
||||
return MakeMappedUnique(mapped);
|
||||
}
|
||||
|
||||
nsresult AttrArray::DoUpdateMappedAttrRuleMapper(
|
||||
nsMappedAttributeElement& aElement) {
|
||||
MOZ_ASSERT(mImpl && mImpl->mMappedAttrs, "Should have mapped attrs here!");
|
||||
|
||||
// First two args don't matter if the assert holds.
|
||||
RefPtr<nsMappedAttributes> mapped = ModifiableMapped(nullptr, false);
|
||||
|
||||
mapped->SetRuleMapper(aElement.GetAttributeMappingFunction());
|
||||
|
||||
return MakeMappedUnique(mapped);
|
||||
}
|
||||
|
||||
void AttrArray::Compact() {
|
||||
if (!mImpl) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mImpl->mAttrCount && !mImpl->mMappedAttrs) {
|
||||
if (!mImpl->mAttrCount && !mImpl->mMappedAttributeBits) {
|
||||
mImpl.reset();
|
||||
return;
|
||||
}
|
||||
|
@ -347,73 +249,12 @@ void AttrArray::Compact() {
|
|||
mImpl.reset(impl);
|
||||
}
|
||||
|
||||
uint32_t AttrArray::DoGetMappedAttrCount() const {
|
||||
MOZ_ASSERT(mImpl && mImpl->mMappedAttrs);
|
||||
return static_cast<uint32_t>(mImpl->mMappedAttrs->Count());
|
||||
}
|
||||
|
||||
nsresult AttrArray::ForceMapped(nsMappedAttributeElement* aContent) {
|
||||
RefPtr<nsMappedAttributes> mapped = ModifiableMapped(aContent, false, 0);
|
||||
return MakeMappedUnique(mapped);
|
||||
}
|
||||
|
||||
void AttrArray::ClearMappedServoStyle() {
|
||||
if (mImpl && mImpl->mMappedAttrs) {
|
||||
mImpl->mMappedAttrs->ClearServoStyle();
|
||||
}
|
||||
}
|
||||
|
||||
nsMappedAttributes* AttrArray::ModifiableMapped(
|
||||
nsMappedAttributeElement* aContent, bool aWillAddAttr, int32_t aAttrCount) {
|
||||
if (mImpl && mImpl->mMappedAttrs) {
|
||||
return mImpl->mMappedAttrs->Clone(aWillAddAttr);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aContent, "Trying to create modifiable without content");
|
||||
|
||||
nsMapRuleToAttributesFunc mapRuleFunc =
|
||||
aContent->GetAttributeMappingFunction();
|
||||
return new (aAttrCount) nsMappedAttributes(
|
||||
aContent->OwnerDoc()->GetAttributeStyles(), mapRuleFunc);
|
||||
}
|
||||
|
||||
nsresult AttrArray::MakeMappedUnique(nsMappedAttributes* aAttributes) {
|
||||
NS_ASSERTION(aAttributes, "missing attributes");
|
||||
|
||||
if (!mImpl && !GrowBy(1)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (!aAttributes->GetAttributeStyles()) {
|
||||
// This doesn't currently happen, but it could if we do loading right
|
||||
RefPtr<nsMappedAttributes> mapped(aAttributes);
|
||||
mapped.swap(mImpl->mMappedAttrs);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<nsMappedAttributes> mapped =
|
||||
aAttributes->GetAttributeStyles()->UniqueMappedAttributes(aAttributes);
|
||||
NS_ENSURE_TRUE(mapped, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (mapped != aAttributes) {
|
||||
// Reset the stylesheet of aAttributes so that it doesn't spend time
|
||||
// trying to remove itself from the hash. There is no risk that aAttributes
|
||||
// is in the hash since it will always have come from ModifiableMapped,
|
||||
// which never returns maps that are in the hash (such hashes are by
|
||||
// nature not modifiable).
|
||||
aAttributes->DropAttributeStylesReference();
|
||||
}
|
||||
mapped.swap(mImpl->mMappedAttrs);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult AttrArray::EnsureCapacityToClone(const AttrArray& aOther) {
|
||||
MOZ_ASSERT(!mImpl,
|
||||
"AttrArray::EnsureCapacityToClone requires the array be empty "
|
||||
"when called");
|
||||
|
||||
uint32_t attrCount = aOther.NonMappedAttrCount();
|
||||
uint32_t attrCount = aOther.AttrCount();
|
||||
if (!attrCount) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -424,7 +265,7 @@ nsresult AttrArray::EnsureCapacityToClone(const AttrArray& aOther) {
|
|||
static_cast<Impl*>(malloc(Impl::AllocationSizeForAttributes(attrCount))));
|
||||
NS_ENSURE_TRUE(mImpl, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
mImpl->mMappedAttrs = nullptr;
|
||||
mImpl->mMappedAttributeBits = 0;
|
||||
mImpl->mCapacity = attrCount;
|
||||
mImpl->mAttrCount = 0;
|
||||
|
||||
|
@ -480,7 +321,7 @@ bool AttrArray::GrowBy(uint32_t aGrowSize) {
|
|||
|
||||
// Set initial counts if we didn't have a buffer before
|
||||
if (needToInitialize) {
|
||||
mImpl->mMappedAttrs = nullptr;
|
||||
mImpl->mMappedAttributeBits = 0;
|
||||
mImpl->mAttrCount = 0;
|
||||
}
|
||||
|
||||
|
@ -490,17 +331,13 @@ bool AttrArray::GrowBy(uint32_t aGrowSize) {
|
|||
|
||||
size_t AttrArray::SizeOfExcludingThis(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
size_t n = 0;
|
||||
if (mImpl) {
|
||||
// Don't add the size taken by *mMappedAttrs because it's shared.
|
||||
|
||||
n += aMallocSizeOf(mImpl.get());
|
||||
|
||||
for (const InternalAttr& attr : NonMappedAttrs()) {
|
||||
n += attr.mValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
if (!mImpl) {
|
||||
return 0;
|
||||
}
|
||||
size_t n = aMallocSizeOf(mImpl.get());
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
n += attr.mValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,12 +22,10 @@
|
|||
#include "nsAttrValue.h"
|
||||
#include "nsCaseTreatment.h"
|
||||
|
||||
class nsMappedAttributes;
|
||||
class nsMappedAttributeElement;
|
||||
|
||||
namespace mozilla {
|
||||
class AttributeStyles;
|
||||
}
|
||||
struct StyleLockedDeclarationBlock;
|
||||
} // namespace mozilla
|
||||
|
||||
class AttrArray {
|
||||
using BorrowedAttrInfo = mozilla::dom::BorrowedAttrInfo;
|
||||
|
@ -36,11 +34,9 @@ class AttrArray {
|
|||
AttrArray() = default;
|
||||
~AttrArray() = default;
|
||||
|
||||
bool HasAttrs() const { return NonMappedAttrCount() || MappedAttrCount(); }
|
||||
bool HasAttrs() const { return !!AttrCount(); }
|
||||
|
||||
uint32_t AttrCount() const {
|
||||
return NonMappedAttrCount() + MappedAttrCount();
|
||||
}
|
||||
uint32_t AttrCount() const { return mImpl ? mImpl->mAttrCount : 0; }
|
||||
|
||||
const nsAttrValue* GetAttr(const nsAtom* aLocalName,
|
||||
int32_t aNamespaceID = kNameSpaceID_None) const;
|
||||
|
@ -61,6 +57,20 @@ class AttrArray {
|
|||
nsresult SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue,
|
||||
bool* aHadValue);
|
||||
|
||||
// This stores the argument and clears the pending mapped attribute evaluation
|
||||
// bit, so after calling this IsPendingMappedAttributeEvaluation() is
|
||||
// guaranteed to return false.
|
||||
void SetMappedDeclarationBlock(
|
||||
already_AddRefed<mozilla::StyleLockedDeclarationBlock>);
|
||||
|
||||
bool IsPendingMappedAttributeEvaluation() const {
|
||||
return mImpl && mImpl->mMappedAttributeBits & 1;
|
||||
}
|
||||
|
||||
mozilla::StyleLockedDeclarationBlock* GetMappedDeclarationBlock() const {
|
||||
return mImpl ? mImpl->GetMappedDeclarationBlock() : nullptr;
|
||||
}
|
||||
|
||||
// Remove the attr at position aPos. The value of the attr is placed in
|
||||
// aValue; any value that was already in aValue is destroyed.
|
||||
nsresult RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue);
|
||||
|
@ -78,34 +88,27 @@ class AttrArray {
|
|||
int32_t IndexOfAttr(const nsAtom* aLocalName,
|
||||
int32_t aNamespaceID = kNameSpaceID_None) const;
|
||||
|
||||
// SetAndSwapMappedAttr swaps the current attribute value with aValue.
|
||||
// If the attribute was unset, an empty value will be swapped into aValue
|
||||
// and aHadValue will be set to false. Otherwise, aHadValue will be set to
|
||||
// true.
|
||||
nsresult SetAndSwapMappedAttr(nsAtom* aLocalName, nsAttrValue& aValue,
|
||||
nsMappedAttributeElement* aContent,
|
||||
bool* aHadValue);
|
||||
|
||||
// Update the rule mapping function on our mapped attributes, if we have any.
|
||||
// We take a nsMappedAttributeElement, not a nsMapRuleToAttributesFunc,
|
||||
// because the latter is defined in a header we can't include here.
|
||||
nsresult UpdateMappedAttrRuleMapper(nsMappedAttributeElement& aElement) {
|
||||
if (!mImpl || !mImpl->mMappedAttrs) {
|
||||
return NS_OK;
|
||||
}
|
||||
return DoUpdateMappedAttrRuleMapper(aElement);
|
||||
}
|
||||
|
||||
void Compact();
|
||||
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
bool HasMappedAttrs() const { return !!GetMapped(); }
|
||||
const nsMappedAttributes* GetMapped() const {
|
||||
return mImpl ? mImpl->mMappedAttrs : nullptr;
|
||||
|
||||
// Mark the element as pending mapped attribute evaluation. This should be
|
||||
// called when a mapped attribute is changed (regardless of connectedness).
|
||||
bool MarkAsPendingPresAttributeEvaluation() {
|
||||
// It'd be great to be able to assert that mImpl is non-null or we're the
|
||||
// <body> element.
|
||||
if (MOZ_UNLIKELY(!mImpl) && !GrowBy(1)) {
|
||||
return false;
|
||||
}
|
||||
InfallibleMarkAsPendingPresAttributeEvaluation();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Force this to have mapped attributes, even if those attributes are empty.
|
||||
nsresult ForceMapped(nsMappedAttributeElement* aContent);
|
||||
// See above.
|
||||
void InfallibleMarkAsPendingPresAttributeEvaluation() {
|
||||
MOZ_ASSERT(mImpl);
|
||||
mImpl->mMappedAttributeBits |= 1;
|
||||
}
|
||||
|
||||
// Clear the servo declaration block on the mapped attributes, if any
|
||||
// Will assert off main thread
|
||||
|
@ -158,8 +161,6 @@ class AttrArray {
|
|||
return val && val->Equals(aValue, aCaseSensitive);
|
||||
}
|
||||
|
||||
nsresult SetMappedAttributeStyles(mozilla::AttributeStyles* aNewStyles);
|
||||
|
||||
struct InternalAttr {
|
||||
nsAttrName mName;
|
||||
nsAttrValue mValue;
|
||||
|
@ -169,20 +170,6 @@ class AttrArray {
|
|||
AttrArray& operator=(const AttrArray& aOther) = delete;
|
||||
|
||||
private:
|
||||
uint32_t NonMappedAttrCount() const { return mImpl ? mImpl->mAttrCount : 0; }
|
||||
|
||||
uint32_t MappedAttrCount() const {
|
||||
return mImpl && mImpl->mMappedAttrs ? DoGetMappedAttrCount() : 0;
|
||||
}
|
||||
|
||||
uint32_t DoGetMappedAttrCount() const;
|
||||
|
||||
// Returns a non-null zero-refcount object.
|
||||
nsMappedAttributes* ModifiableMapped(nsMappedAttributeElement* aContent,
|
||||
bool aWillAddAttr,
|
||||
int32_t aAttrCount = 1);
|
||||
nsresult MakeMappedUnique(nsMappedAttributes* aAttributes);
|
||||
|
||||
bool GrowBy(uint32_t aGrowSize);
|
||||
|
||||
// Tries to create an attribute, growing the buffer if needed, with the given
|
||||
|
@ -195,30 +182,22 @@ class AttrArray {
|
|||
template <typename Name>
|
||||
nsresult AddNewAttribute(Name*, nsAttrValue&);
|
||||
|
||||
/**
|
||||
* Guts of UpdateMappedAttrRuleMapper for the case when we have mapped attrs.
|
||||
*/
|
||||
nsresult DoUpdateMappedAttrRuleMapper(nsMappedAttributeElement& aElement);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Disable MSVC warning 'nonstandard extension used: zero-sized array in
|
||||
// struct/union'
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4200)
|
||||
#endif
|
||||
class Impl {
|
||||
public:
|
||||
constexpr static size_t AllocationSizeForAttributes(uint32_t aAttrCount) {
|
||||
return sizeof(Impl) + aAttrCount * sizeof(InternalAttr);
|
||||
}
|
||||
|
||||
auto NonMappedAttrs() const {
|
||||
mozilla::StyleLockedDeclarationBlock* GetMappedDeclarationBlock() const {
|
||||
return reinterpret_cast<mozilla::StyleLockedDeclarationBlock*>(
|
||||
mMappedAttributeBits & ~uintptr_t(1));
|
||||
}
|
||||
|
||||
auto Attrs() const {
|
||||
return mozilla::Span<const InternalAttr>{mBuffer, mAttrCount};
|
||||
}
|
||||
|
||||
auto NonMappedAttrs() {
|
||||
return mozilla::Span<InternalAttr>{mBuffer, mAttrCount};
|
||||
}
|
||||
auto Attrs() { return mozilla::Span<InternalAttr>{mBuffer, mAttrCount}; }
|
||||
|
||||
Impl(const Impl&) = delete;
|
||||
Impl(Impl&&) = delete;
|
||||
|
@ -227,23 +206,25 @@ class AttrArray {
|
|||
uint32_t mAttrCount;
|
||||
uint32_t mCapacity; // In number of InternalAttrs
|
||||
|
||||
// Manually refcounted.
|
||||
nsMappedAttributes* mMappedAttrs;
|
||||
// mMappedAttributeBits is a tagged pointer of a
|
||||
// StyleLockedDeclarationBlock, which holds the style information that our
|
||||
// attributes map to.
|
||||
//
|
||||
// If the lower bit is set, then our mapped attributes are dirty. This just
|
||||
// means that we might have mapped attributes (or used to and no longer
|
||||
// have), and are pending an update to recompute our declaration.
|
||||
uintptr_t mMappedAttributeBits = 0;
|
||||
|
||||
// Allocated in the same buffer as `Impl`.
|
||||
InternalAttr mBuffer[0];
|
||||
};
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
mozilla::Span<InternalAttr> NonMappedAttrs() {
|
||||
return mImpl ? mImpl->NonMappedAttrs() : mozilla::Span<InternalAttr>();
|
||||
mozilla::Span<InternalAttr> Attrs() {
|
||||
return mImpl ? mImpl->Attrs() : mozilla::Span<InternalAttr>();
|
||||
}
|
||||
|
||||
mozilla::Span<const InternalAttr> NonMappedAttrs() const {
|
||||
return mImpl ? mImpl->NonMappedAttrs()
|
||||
: mozilla::Span<const InternalAttr>();
|
||||
mozilla::Span<const InternalAttr> Attrs() const {
|
||||
return mImpl ? mImpl->Attrs() : mozilla::Span<const InternalAttr>();
|
||||
}
|
||||
|
||||
mozilla::UniquePtr<Impl> mImpl;
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include "mozilla/ExtensionPolicyService.h"
|
||||
#include "mozilla/FullscreenChange.h"
|
||||
#include "mozilla/GlobalStyleSheetCache.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/HTMLEditor.h"
|
||||
#include "mozilla/HoldDropJSObjects.h"
|
||||
#include "mozilla/IdentifierMapEntry.h"
|
||||
|
@ -8653,11 +8654,43 @@ already_AddRefed<Attr> Document::CreateAttributeNS(
|
|||
return attribute.forget();
|
||||
}
|
||||
|
||||
void Document::ResolveScheduledSVGPresAttrs() {
|
||||
for (SVGElement* svg : mLazySVGPresElements) {
|
||||
svg->UpdateContentDeclarationBlock();
|
||||
void Document::ScheduleForPresAttrEvaluation(Element* aElement) {
|
||||
MOZ_ASSERT(aElement->IsInComposedDoc());
|
||||
DebugOnly<bool> inserted = mLazyPresElements.EnsureInserted(aElement);
|
||||
MOZ_ASSERT(inserted);
|
||||
if (aElement->HasServoData()) {
|
||||
// TODO(emilio): RESTYLE_SELF is too strong, there should be no need to
|
||||
// re-selector-match, but right now this is needed to pick up the new mapped
|
||||
// attributes. We need something like RESTYLE_STYLE_ATTRIBUTE but for mapped
|
||||
// attributes.
|
||||
nsLayoutUtils::PostRestyleEvent(aElement, RestyleHint::RESTYLE_SELF,
|
||||
nsChangeHint(0));
|
||||
}
|
||||
mLazySVGPresElements.Clear();
|
||||
}
|
||||
|
||||
void Document::UnscheduleForPresAttrEvaluation(Element* aElement) {
|
||||
mLazyPresElements.Remove(aElement);
|
||||
}
|
||||
|
||||
void Document::DoResolveScheduledPresAttrs() {
|
||||
MOZ_ASSERT(!mLazyPresElements.IsEmpty());
|
||||
for (Element* el : mLazyPresElements) {
|
||||
MOZ_ASSERT(el->IsInComposedDoc(),
|
||||
"Un-schedule when removing from the document");
|
||||
MOZ_ASSERT(el->IsPendingMappedAttributeEvaluation());
|
||||
if (auto* svg = SVGElement::FromNode(el)) {
|
||||
// SVG does its own (very similar) thing, for now at least.
|
||||
svg->UpdateMappedDeclarationBlock();
|
||||
} else {
|
||||
MappedDeclarationsBuilder builder(*el, *this,
|
||||
el->GetMappedAttributeStyle());
|
||||
auto function = el->GetAttributeMappingFunction();
|
||||
function(builder);
|
||||
el->SetMappedDeclarationBlock(builder.TakeDeclarationBlock());
|
||||
}
|
||||
MOZ_ASSERT(!el->IsPendingMappedAttributeEvaluation());
|
||||
}
|
||||
mLazyPresElements.Clear();
|
||||
}
|
||||
|
||||
already_AddRefed<nsSimpleContentList> Document::BlockedNodesByClassifier()
|
||||
|
|
|
@ -1379,25 +1379,25 @@ class Document : public nsINode,
|
|||
|
||||
void NotifyLayerManagerRecreated();
|
||||
|
||||
/**
|
||||
* Add an SVG element to the list of elements that need
|
||||
* their mapped attributes resolved to a Servo declaration block.
|
||||
*
|
||||
* These are weak pointers, please manually unschedule them when an element
|
||||
* is removed.
|
||||
*/
|
||||
void ScheduleSVGForPresAttrEvaluation(SVGElement* aSVG) {
|
||||
mLazySVGPresElements.Insert(aSVG);
|
||||
}
|
||||
// Add an element to the list of elements that need their mapped attributes
|
||||
// resolved to a declaration block.
|
||||
//
|
||||
// These are weak pointers, manually unschedule them when an element is
|
||||
// removed from the tree.
|
||||
void ScheduleForPresAttrEvaluation(Element* aElement);
|
||||
|
||||
// Unschedule an element scheduled by ScheduleFrameRequestCallback (e.g. for
|
||||
// when it is destroyed)
|
||||
void UnscheduleSVGForPresAttrEvaluation(SVGElement* aSVG) {
|
||||
mLazySVGPresElements.Remove(aSVG);
|
||||
}
|
||||
// Un-schedule an element scheduled by ScheduleForPresAttrEvaluation,
|
||||
// generally when it's unbound from the tree.
|
||||
void UnscheduleForPresAttrEvaluation(Element* aElement);
|
||||
|
||||
// Resolve all SVG pres attrs scheduled in ScheduleSVGForPresAttrEvaluation
|
||||
void ResolveScheduledSVGPresAttrs();
|
||||
// Resolve all presentational attributes scheduled in
|
||||
// ScheduleForPresAttrEvaluation
|
||||
void ResolveScheduledPresAttrs() {
|
||||
if (mLazyPresElements.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
DoResolveScheduledPresAttrs();
|
||||
}
|
||||
|
||||
Maybe<ClientInfo> GetClientInfo() const;
|
||||
Maybe<ClientState> GetClientState() const;
|
||||
|
@ -1564,6 +1564,8 @@ class Document : public nsINode,
|
|||
|
||||
void DoUnblockOnload();
|
||||
|
||||
void DoResolveScheduledPresAttrs();
|
||||
|
||||
void RetrieveRelevantHeaders(nsIChannel* aChannel);
|
||||
|
||||
void TryChannelCharset(nsIChannel* aChannel, int32_t& aCharsetSource,
|
||||
|
@ -5257,10 +5259,9 @@ class Document : public nsINode,
|
|||
|
||||
RefPtr<DOMStyleSheetSetList> mStyleSheetSetList;
|
||||
|
||||
// We lazily calculate declaration blocks for SVG elements with mapped
|
||||
// attributes in Servo mode. This list contains all elements which need lazy
|
||||
// resolution.
|
||||
nsTHashSet<SVGElement*> mLazySVGPresElements;
|
||||
// We lazily calculate declaration blocks for elements with mapped
|
||||
// attributes. This set contains all elements which need lazy resolution.
|
||||
nsTHashSet<Element*> mLazyPresElements;
|
||||
|
||||
nsTHashSet<RefPtr<nsAtom>> mLanguagesUsed;
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/PointerLockManager.h"
|
||||
|
@ -1859,6 +1860,9 @@ nsresult Element::BindToTree(BindContext& aContext, nsINode& aParent) {
|
|||
}
|
||||
|
||||
if (IsInComposedDoc()) {
|
||||
if (IsPendingMappedAttributeEvaluation()) {
|
||||
aContext.OwnerDoc().ScheduleForPresAttrEvaluation(this);
|
||||
}
|
||||
// Connected callback must be enqueued whenever a custom element becomes
|
||||
// connected.
|
||||
if (CustomElementData* data = GetCustomElementData()) {
|
||||
|
@ -2062,8 +2066,7 @@ void Element::UnbindFromTree(bool aNullParent) {
|
|||
if (document) {
|
||||
// Disconnected must be enqueued whenever a connected custom element becomes
|
||||
// disconnected.
|
||||
CustomElementData* data = GetCustomElementData();
|
||||
if (data) {
|
||||
if (CustomElementData* data = GetCustomElementData()) {
|
||||
if (data->mState == CustomElementData::State::eCustom) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
ElementCallbackType::eDisconnected, this, {});
|
||||
|
@ -2074,6 +2077,10 @@ void Element::UnbindFromTree(bool aNullParent) {
|
|||
}
|
||||
}
|
||||
|
||||
if (IsPendingMappedAttributeEvaluation()) {
|
||||
document->UnscheduleForPresAttrEvaluation(this);
|
||||
}
|
||||
|
||||
if (HasLastRememberedBSize() || HasLastRememberedISize()) {
|
||||
// Need to remove the last remembered size at the next ResizeObserver
|
||||
// opportunity, so observe the element. But if already observed, we still
|
||||
|
@ -2170,11 +2177,24 @@ nsresult Element::SetInlineStyleDeclaration(DeclarationBlock& aDeclaration,
|
|||
NS_IMETHODIMP_(bool)
|
||||
Element::IsAttributeMapped(const nsAtom* aAttribute) const { return false; }
|
||||
|
||||
nsMapRuleToAttributesFunc Element::GetAttributeMappingFunction() const {
|
||||
return &MapNoAttributesInto;
|
||||
}
|
||||
|
||||
void Element::MapNoAttributesInto(mozilla::MappedDeclarationsBuilder&) {}
|
||||
|
||||
nsChangeHint Element::GetAttributeChangeHint(const nsAtom* aAttribute,
|
||||
int32_t aModType) const {
|
||||
return nsChangeHint(0);
|
||||
}
|
||||
|
||||
void Element::SetMappedDeclarationBlock(
|
||||
already_AddRefed<StyleLockedDeclarationBlock> aDeclarations) {
|
||||
MOZ_ASSERT(IsPendingMappedAttributeEvaluation());
|
||||
mAttrs.SetMappedDeclarationBlock(std::move(aDeclarations));
|
||||
MOZ_ASSERT(!IsPendingMappedAttributeEvaluation());
|
||||
}
|
||||
|
||||
bool Element::FindAttributeDependence(const nsAtom* aAttribute,
|
||||
const MappedAttributeEntry* const aMaps[],
|
||||
uint32_t aMapCount) {
|
||||
|
@ -2550,11 +2570,10 @@ nsresult Element::SetAttrAndNotify(
|
|||
nsIPrincipal* aSubjectPrincipal, uint8_t aModType, bool aFireMutation,
|
||||
bool aNotify, bool aCallAfterSetAttr, Document* aComposedDocument,
|
||||
const mozAutoDocUpdate& aGuard) {
|
||||
nsresult rv;
|
||||
nsMutationGuard::DidMutate();
|
||||
|
||||
// Copy aParsedValue for later use since it will be lost when we call
|
||||
// SetAndSwapMappedAttr below
|
||||
// SetAndSwapAttr below
|
||||
nsAttrValue valueForAfterSetAttr;
|
||||
if (aCallAfterSetAttr || GetCustomElementData()) {
|
||||
valueForAfterSetAttr.SetTo(aParsedValue);
|
||||
|
@ -2570,20 +2589,19 @@ nsresult Element::SetAttrAndNotify(
|
|||
hadDirAuto = HasDirAuto(); // already takes bdi into account
|
||||
}
|
||||
|
||||
// XXXbz Perhaps we should push up the attribute mapping function
|
||||
// stuff to Element?
|
||||
if (!IsAttributeMapped(aName) ||
|
||||
!SetAndSwapMappedAttribute(aName, aParsedValue, &oldValueSet, &rv)) {
|
||||
rv = mAttrs.SetAndSwapAttr(aName, aParsedValue, &oldValueSet);
|
||||
MOZ_TRY(mAttrs.SetAndSwapAttr(aName, aParsedValue, &oldValueSet));
|
||||
if (IsAttributeMapped(aName) && !IsPendingMappedAttributeEvaluation()) {
|
||||
mAttrs.InfallibleMarkAsPendingPresAttributeEvaluation();
|
||||
if (Document* doc = GetComposedDoc()) {
|
||||
doc->ScheduleForPresAttrEvaluation(this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RefPtr<mozilla::dom::NodeInfo> ni;
|
||||
ni = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, aPrefix, aNamespaceID,
|
||||
ATTRIBUTE_NODE);
|
||||
|
||||
rv = mAttrs.SetAndSwapAttr(ni, aParsedValue, &oldValueSet);
|
||||
RefPtr<mozilla::dom::NodeInfo> ni =
|
||||
mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, aPrefix, aNamespaceID,
|
||||
ATTRIBUTE_NODE);
|
||||
MOZ_TRY(mAttrs.SetAndSwapAttr(ni, aParsedValue, &oldValueSet));
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PostIdMaybeChange(aNamespaceID, aName, &valueForAfterSetAttr);
|
||||
|
||||
|
@ -2723,12 +2741,6 @@ bool Element::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Element::SetAndSwapMappedAttribute(nsAtom* aName, nsAttrValue& aValue,
|
||||
bool* aValueWasSet, nsresult* aRetval) {
|
||||
*aRetval = NS_OK;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Element::BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
||||
const nsAttrValue* aValue, bool aNotify) {
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
|
@ -2887,14 +2899,21 @@ nsresult Element::UnsetAttr(int32_t aNameSpaceID, nsAtom* aName, bool aNotify) {
|
|||
bool hadValidDir = false;
|
||||
bool hadDirAuto = false;
|
||||
|
||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) {
|
||||
hadValidDir = HasValidDir() || IsHTMLElement(nsGkAtoms::bdi);
|
||||
hadDirAuto = HasDirAuto(); // already takes bdi into account
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::dir) {
|
||||
hadValidDir = HasValidDir() || IsHTMLElement(nsGkAtoms::bdi);
|
||||
hadDirAuto = HasDirAuto(); // already takes bdi into account
|
||||
}
|
||||
if (IsAttributeMapped(aName) && !IsPendingMappedAttributeEvaluation()) {
|
||||
mAttrs.InfallibleMarkAsPendingPresAttributeEvaluation();
|
||||
if (Document* doc = GetComposedDoc()) {
|
||||
doc->ScheduleForPresAttrEvaluation(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsAttrValue oldValue;
|
||||
nsresult rv = mAttrs.RemoveAttrAt(index, oldValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
MOZ_TRY(mAttrs.RemoveAttrAt(index, oldValue));
|
||||
|
||||
PostIdMaybeChange(aNameSpaceID, aName, nullptr);
|
||||
|
||||
|
|
|
@ -93,7 +93,6 @@ class nsIPrincipal;
|
|||
class nsIScreen;
|
||||
class nsIScrollableFrame;
|
||||
class nsIURI;
|
||||
class nsMappedAttributes;
|
||||
class nsPresContext;
|
||||
class nsWindowSizes;
|
||||
struct JSContext;
|
||||
|
@ -105,6 +104,7 @@ class nsGetterAddRefs;
|
|||
|
||||
namespace mozilla {
|
||||
class DeclarationBlock;
|
||||
class MappedDeclarationsBuilder;
|
||||
class ErrorResult;
|
||||
class OOMReporter;
|
||||
class SMILAttr;
|
||||
|
@ -144,6 +144,8 @@ typedef nsTHashMap<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>
|
|||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
using nsMapRuleToAttributesFunc = void (*)(mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
// Declared here because of include hell.
|
||||
extern "C" bool Servo_Element_IsDisplayContents(const mozilla::dom::Element*);
|
||||
|
||||
|
@ -387,11 +389,15 @@ class Element : public FragmentOrElement {
|
|||
/**
|
||||
* Get the mapped attributes, if any, for this element.
|
||||
*/
|
||||
const nsMappedAttributes* GetMappedAttributes() const {
|
||||
return mAttrs.GetMapped();
|
||||
StyleLockedDeclarationBlock* GetMappedAttributeStyle() const {
|
||||
return mAttrs.GetMappedDeclarationBlock();
|
||||
}
|
||||
|
||||
void ClearMappedServoStyle() { mAttrs.ClearMappedServoStyle(); }
|
||||
bool IsPendingMappedAttributeEvaluation() const {
|
||||
return mAttrs.IsPendingMappedAttributeEvaluation();
|
||||
}
|
||||
|
||||
void SetMappedDeclarationBlock(already_AddRefed<StyleLockedDeclarationBlock>);
|
||||
|
||||
/**
|
||||
* InlineStyleDeclarationWillChange is called before SetInlineStyleDeclaration
|
||||
|
@ -457,14 +463,16 @@ class Element : public FragmentOrElement {
|
|||
virtual nsIMozBrowserFrame* GetAsMozBrowserFrame() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Is the attribute named stored in the mapped attributes?
|
||||
*
|
||||
* // XXXbz we use this method in HasAttributeDependentStyle, so svg
|
||||
* returns true here even though it stores nothing in the mapped
|
||||
* attributes.
|
||||
* Is the attribute named aAttribute a mapped attribute?
|
||||
*/
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const;
|
||||
|
||||
nsresult BindToTree(BindContext&, nsINode& aParent) override;
|
||||
void UnbindFromTree(bool aNullParent = true) override;
|
||||
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
|
||||
static void MapNoAttributesInto(mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
/**
|
||||
* Get a hint that tells the style system what to do when
|
||||
* an attribute on this node changes, if something needs to happen
|
||||
|
@ -806,10 +814,6 @@ class Element : public FragmentOrElement {
|
|||
|
||||
void UpdateEditableState(bool aNotify) override;
|
||||
|
||||
nsresult BindToTree(BindContext&, nsINode& aParent) override;
|
||||
|
||||
void UnbindFromTree(bool aNullParent = true) override;
|
||||
|
||||
/**
|
||||
* Normalizes an attribute name and returns it as a nodeinfo if an attribute
|
||||
* with that name exists. This method is intended for character case
|
||||
|
@ -1893,27 +1897,6 @@ class Element : public FragmentOrElement {
|
|||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
/**
|
||||
* Try to set the attribute as a mapped attribute, if applicable. This will
|
||||
* only be called for attributes that are in the null namespace and only on
|
||||
* attributes that returned true when passed to IsAttributeMapped. The
|
||||
* caller will not try to set the attr in any other way if this method
|
||||
* returns true (the value of aRetval does not matter for that purpose).
|
||||
*
|
||||
* @param aName the name of the attribute
|
||||
* @param aValue the nsAttrValue to set. Will be swapped with the existing
|
||||
* value of the attribute if the attribute already exists.
|
||||
* @param [out] aValueWasSet If the attribute was not set previously,
|
||||
* aValue will be swapped with an empty attribute
|
||||
* and aValueWasSet will be set to false. Otherwise,
|
||||
* aValueWasSet will be set to true and aValue will
|
||||
* contain the previous value set.
|
||||
* @param [out] aRetval the nsresult status of the operation, if any.
|
||||
* @return true if the setting was attempted, false otherwise.
|
||||
*/
|
||||
virtual bool SetAndSwapMappedAttribute(nsAtom* aName, nsAttrValue& aValue,
|
||||
bool* aValueWasSet, nsresult* aRetval);
|
||||
|
||||
/**
|
||||
* Hook that is called by Element::SetAttr to allow subclasses to
|
||||
* deal with attribute sets. This will only be called after we verify that
|
||||
|
|
|
@ -93,8 +93,6 @@ EXPORTS += [
|
|||
"nsJSEnvironment.h",
|
||||
"nsJSUtils.h",
|
||||
"nsLineBreaker.h",
|
||||
"nsMappedAttributeElement.h",
|
||||
"nsMappedAttributes.h",
|
||||
"nsNameSpaceManager.h",
|
||||
"nsNodeInfoManager.h",
|
||||
"nsPIDOMWindow.h",
|
||||
|
@ -411,8 +409,6 @@ UNIFIED_SOURCES += [
|
|||
"nsJSEnvironment.cpp",
|
||||
"nsJSUtils.cpp",
|
||||
"nsLineBreaker.cpp",
|
||||
"nsMappedAttributeElement.cpp",
|
||||
"nsMappedAttributes.cpp",
|
||||
"nsMimeTypeArray.cpp",
|
||||
"nsNameSpaceManager.cpp",
|
||||
"nsNoDataProtocolContentPolicy.cpp",
|
||||
|
|
|
@ -340,7 +340,6 @@
|
|||
#include "nsJSUtils.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsLiteralString.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsMargin.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
|
@ -1966,7 +1965,6 @@ void nsContentUtils::Shutdown() {
|
|||
}
|
||||
|
||||
TextControlState::Shutdown();
|
||||
nsMappedAttributes::Shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "nsHTMLDocument.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsView.h"
|
||||
#include "nsBaseWidget.h"
|
||||
#include "nsQueryObject.h"
|
||||
|
@ -1067,20 +1066,11 @@ void nsFrameLoader::MarginsChanged() {
|
|||
// that needs to be updated
|
||||
if (Document* doc = docShell->GetDocument()) {
|
||||
for (nsINode* cur = doc; cur; cur = cur->GetNextNode()) {
|
||||
if (cur->IsHTMLElement(nsGkAtoms::body)) {
|
||||
static_cast<HTMLBodyElement*>(cur)->ClearMappedServoStyle();
|
||||
if (auto* body = HTMLBodyElement::FromNode(cur)) {
|
||||
body->FrameMarginsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger a restyle if there's a prescontext
|
||||
// FIXME: This could do something much less expensive.
|
||||
if (nsPresContext* presContext = docShell->GetPresContext()) {
|
||||
// rebuild, because now the same nsMappedAttributes* will produce
|
||||
// a different style
|
||||
presContext->RebuildAllStyleData(nsChangeHint(0),
|
||||
RestyleHint::RestyleSubtree());
|
||||
}
|
||||
}
|
||||
|
||||
bool nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "nsMappedAttributeElement.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
|
||||
bool nsMappedAttributeElement::SetAndSwapMappedAttribute(nsAtom* aName,
|
||||
nsAttrValue& aValue,
|
||||
bool* aValueWasSet,
|
||||
nsresult* aRetval) {
|
||||
*aRetval = mAttrs.SetAndSwapMappedAttr(aName, aValue, this, aValueWasSet);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsMapRuleToAttributesFunc
|
||||
nsMappedAttributeElement::GetAttributeMappingFunction() const {
|
||||
return &MapNoAttributesInto;
|
||||
}
|
||||
|
||||
void nsMappedAttributeElement::MapNoAttributesInto(
|
||||
const nsMappedAttributes*, mozilla::MappedDeclarations&) {}
|
||||
|
||||
void nsMappedAttributeElement::NodeInfoChanged(Document* aOldDoc) {
|
||||
if (mAttrs.HasMappedAttrs()) {
|
||||
mAttrs.SetMappedAttributeStyles(OwnerDoc()->GetAttributeStyles());
|
||||
}
|
||||
nsMappedAttributeElementBase::NodeInfoChanged(aOldDoc);
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
/**
|
||||
* nsMappedAttributeElement is the base for elements supporting style mapped
|
||||
* attributes via nsMappedAttributes (HTML and MathML).
|
||||
*/
|
||||
|
||||
#ifndef NS_MAPPEDATTRIBUTEELEMENT_H_
|
||||
#define NS_MAPPEDATTRIBUTEELEMENT_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsStyledElement.h"
|
||||
|
||||
namespace mozilla {
|
||||
class MappedDeclarations;
|
||||
}
|
||||
|
||||
class nsMappedAttributes;
|
||||
struct nsRuleData;
|
||||
|
||||
using nsMapRuleToAttributesFunc = void (*)(
|
||||
const nsMappedAttributes* aAttributes, mozilla::MappedDeclarations&);
|
||||
|
||||
using nsMappedAttributeElementBase = nsStyledElement;
|
||||
|
||||
class nsMappedAttributeElement : public nsMappedAttributeElementBase {
|
||||
protected:
|
||||
explicit nsMappedAttributeElement(
|
||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: nsMappedAttributeElementBase(std::move(aNodeInfo)) {}
|
||||
|
||||
public:
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
|
||||
|
||||
static void MapNoAttributesInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
|
||||
virtual bool SetAndSwapMappedAttribute(nsAtom* aName, nsAttrValue& aValue,
|
||||
bool* aValueWasSet,
|
||||
nsresult* aRetval) override;
|
||||
|
||||
virtual void NodeInfoChanged(mozilla::dom::Document* aOldDoc) override;
|
||||
};
|
||||
|
||||
#endif // NS_MAPPEDATTRIBUTEELEMENT_H_
|
|
@ -1,258 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
/*
|
||||
* A unique per-element set of attributes that is used as an
|
||||
* nsIStyleRule; used to implement presentational attributes.
|
||||
*/
|
||||
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/AttributeStyles.h"
|
||||
#include "mozilla/DeclarationBlock.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
bool nsMappedAttributes::sShuttingDown = false;
|
||||
nsTArray<void*>* nsMappedAttributes::sCachedMappedAttributeAllocations =
|
||||
nullptr;
|
||||
|
||||
void nsMappedAttributes::Shutdown() {
|
||||
sShuttingDown = true;
|
||||
if (sCachedMappedAttributeAllocations) {
|
||||
for (uint32_t i = 0; i < sCachedMappedAttributeAllocations->Length(); ++i) {
|
||||
void* cachedValue = (*sCachedMappedAttributeAllocations)[i];
|
||||
::operator delete(cachedValue);
|
||||
}
|
||||
}
|
||||
|
||||
delete sCachedMappedAttributeAllocations;
|
||||
sCachedMappedAttributeAllocations = nullptr;
|
||||
}
|
||||
|
||||
nsMappedAttributes::nsMappedAttributes(AttributeStyles* aAttrStyles,
|
||||
nsMapRuleToAttributesFunc aMapRuleFunc)
|
||||
: mAttrCount(0),
|
||||
mAttrStyles(aAttrStyles),
|
||||
mRuleMapper(aMapRuleFunc),
|
||||
mServoStyle(nullptr) {
|
||||
MOZ_ASSERT(mRefCnt == 0); // Ensure caching works as expected.
|
||||
}
|
||||
|
||||
nsMappedAttributes::nsMappedAttributes(const nsMappedAttributes& aCopy)
|
||||
: mAttrCount(aCopy.mAttrCount),
|
||||
mAttrStyles(aCopy.mAttrStyles),
|
||||
mRuleMapper(aCopy.mRuleMapper),
|
||||
// This is only called by ::Clone, which is used to create independent
|
||||
// nsMappedAttributes objects which should not share a DeclarationBlock
|
||||
mServoStyle(nullptr) {
|
||||
MOZ_ASSERT(mBufferSize >= aCopy.mAttrCount, "can't fit attributes");
|
||||
MOZ_ASSERT(mRefCnt == 0); // Ensure caching works as expected.
|
||||
|
||||
uint32_t i = 0;
|
||||
for (const InternalAttr& attr : aCopy.Attrs()) {
|
||||
new (&mBuffer[i++]) InternalAttr(attr);
|
||||
}
|
||||
}
|
||||
|
||||
nsMappedAttributes::~nsMappedAttributes() {
|
||||
if (mAttrStyles) {
|
||||
mAttrStyles->DropMappedAttributes(this);
|
||||
}
|
||||
|
||||
for (InternalAttr& attr : Attrs()) {
|
||||
attr.~InternalAttr();
|
||||
}
|
||||
}
|
||||
|
||||
nsMappedAttributes* nsMappedAttributes::Clone(bool aWillAddAttr) {
|
||||
uint32_t extra = aWillAddAttr ? 1 : 0;
|
||||
|
||||
// This will call the overridden operator new
|
||||
return new (mAttrCount + extra) nsMappedAttributes(*this);
|
||||
}
|
||||
|
||||
void* nsMappedAttributes::operator new(size_t aSize,
|
||||
uint32_t aAttrCount) noexcept(true) {
|
||||
size_t size = aSize + aAttrCount * sizeof(InternalAttr);
|
||||
|
||||
if (sCachedMappedAttributeAllocations) {
|
||||
void* cached = sCachedMappedAttributeAllocations->SafeElementAt(aAttrCount);
|
||||
if (cached) {
|
||||
(*sCachedMappedAttributeAllocations)[aAttrCount] = nullptr;
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
|
||||
void* newAttrs = ::operator new(size);
|
||||
|
||||
#ifdef DEBUG
|
||||
static_cast<nsMappedAttributes*>(newAttrs)->mBufferSize = aAttrCount;
|
||||
#endif
|
||||
return newAttrs;
|
||||
}
|
||||
|
||||
void nsMappedAttributes::LastRelease() {
|
||||
if (!sShuttingDown) {
|
||||
if (!sCachedMappedAttributeAllocations) {
|
||||
sCachedMappedAttributeAllocations = new nsTArray<void*>();
|
||||
}
|
||||
|
||||
// Ensure the cache array is at least mAttrCount + 1 long and
|
||||
// that each item is either null or pointing to a cached item.
|
||||
// The size of the array is capped because mapped attributes are defined
|
||||
// statically in element implementations.
|
||||
sCachedMappedAttributeAllocations->SetCapacity(mAttrCount + 1);
|
||||
for (uint32_t i = sCachedMappedAttributeAllocations->Length();
|
||||
i < (uint32_t(mAttrCount) + 1); ++i) {
|
||||
sCachedMappedAttributeAllocations->AppendElement(nullptr);
|
||||
}
|
||||
|
||||
if (!(*sCachedMappedAttributeAllocations)[mAttrCount]) {
|
||||
void* memoryToCache = this;
|
||||
this->~nsMappedAttributes();
|
||||
(*sCachedMappedAttributeAllocations)[mAttrCount] = memoryToCache;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
void nsMappedAttributes::SetAndSwapAttr(nsAtom* aAttrName, nsAttrValue& aValue,
|
||||
bool* aValueWasSet) {
|
||||
MOZ_ASSERT(aAttrName, "null name");
|
||||
*aValueWasSet = false;
|
||||
uint32_t i;
|
||||
for (i = 0; i < mAttrCount && !mBuffer[i].mName.IsSmaller(aAttrName); ++i) {
|
||||
if (mBuffer[i].mName.Equals(aAttrName)) {
|
||||
mBuffer[i].mValue.SwapValueWith(aValue);
|
||||
*aValueWasSet = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mBufferSize >= mAttrCount + 1, "can't fit attributes");
|
||||
|
||||
if (mAttrCount != i) {
|
||||
memmove(&mBuffer[i + 1], &mBuffer[i],
|
||||
(mAttrCount - i) * sizeof(InternalAttr));
|
||||
}
|
||||
|
||||
new (&mBuffer[i].mName) nsAttrName(aAttrName);
|
||||
new (&mBuffer[i].mValue) nsAttrValue();
|
||||
mBuffer[i].mValue.SwapValueWith(aValue);
|
||||
++mAttrCount;
|
||||
}
|
||||
|
||||
const nsAttrValue* nsMappedAttributes::GetAttr(const nsAtom* aAttrName) const {
|
||||
MOZ_ASSERT(aAttrName, "null name");
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.Equals(aAttrName)) {
|
||||
return &attr.mValue;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const nsAttrValue* nsMappedAttributes::GetAttr(
|
||||
const nsAString& aAttrName) const {
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.Atom()->Equals(aAttrName)) {
|
||||
return &attr.mValue;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool nsMappedAttributes::Equals(const nsMappedAttributes* aOther) const {
|
||||
if (this == aOther) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mRuleMapper != aOther->mRuleMapper || mAttrCount != aOther->mAttrCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < mAttrCount; ++i) {
|
||||
if (!mBuffer[i].mName.Equals(aOther->mBuffer[i].mName) ||
|
||||
!mBuffer[i].mValue.Equals(aOther->mBuffer[i].mValue)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PLDHashNumber nsMappedAttributes::HashValue() const {
|
||||
PLDHashNumber hash = HashGeneric(mRuleMapper);
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
hash = AddToHash(hash, attr.mName.HashValue(), attr.mValue.HashValue());
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
void nsMappedAttributes::SetAttributeStyles(AttributeStyles* aAttrStyles) {
|
||||
MOZ_ASSERT(!mAttrStyles,
|
||||
"Should either drop the sheet reference manually, "
|
||||
"or drop the mapped attributes");
|
||||
mAttrStyles = aAttrStyles; // not ref counted
|
||||
}
|
||||
|
||||
void nsMappedAttributes::RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue) {
|
||||
mBuffer[aPos].mValue.SwapValueWith(aValue);
|
||||
mBuffer[aPos].~InternalAttr();
|
||||
memmove(&mBuffer[aPos], &mBuffer[aPos + 1],
|
||||
(mAttrCount - aPos - 1) * sizeof(InternalAttr));
|
||||
mAttrCount--;
|
||||
}
|
||||
|
||||
const nsAttrName* nsMappedAttributes::GetExistingAttrNameFromQName(
|
||||
const nsAString& aName) const {
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
if (attr.mName.Atom()->Equals(aName)) {
|
||||
return &attr.mName;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t nsMappedAttributes::IndexOfAttr(const nsAtom* aLocalName) const {
|
||||
for (uint32_t i = 0; i < mAttrCount; ++i) {
|
||||
if (mBuffer[i].mName.Equals(aLocalName)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t nsMappedAttributes::SizeOfIncludingThis(
|
||||
MallocSizeOf aMallocSizeOf) const {
|
||||
MOZ_ASSERT(mBufferSize >= mAttrCount, "can't fit attributes");
|
||||
|
||||
size_t n = aMallocSizeOf(this);
|
||||
for (const InternalAttr& attr : Attrs()) {
|
||||
n += attr.mValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void nsMappedAttributes::LazilyResolveServoDeclaration(dom::Document* aDoc) {
|
||||
MOZ_ASSERT(!mServoStyle,
|
||||
"LazilyResolveServoDeclaration should not be called if "
|
||||
"mServoStyle is already set");
|
||||
if (mRuleMapper) {
|
||||
MappedDeclarations declarations(
|
||||
aDoc, Servo_DeclarationBlock_CreateEmpty().Consume());
|
||||
(*mRuleMapper)(this, declarations);
|
||||
mServoStyle = declarations.TakeDeclarationBlock();
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
/*
|
||||
* A unique per-element set of attributes that is used as an
|
||||
* nsIStyleRule; used to implement presentational attributes.
|
||||
*/
|
||||
|
||||
#ifndef nsMappedAttributes_h___
|
||||
#define nsMappedAttributes_h___
|
||||
|
||||
#include "AttrArray.h"
|
||||
#include "nsMappedAttributeElement.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ServoBindingTypes.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
class nsAtom;
|
||||
|
||||
namespace mozilla {
|
||||
class AttributeStyles;
|
||||
}
|
||||
|
||||
class nsMappedAttributes final {
|
||||
using InternalAttr = AttrArray::InternalAttr;
|
||||
|
||||
public:
|
||||
nsMappedAttributes(mozilla::AttributeStyles*, nsMapRuleToAttributesFunc);
|
||||
|
||||
// Do not return null.
|
||||
void* operator new(size_t size, uint32_t aAttrCount = 1) noexcept(true);
|
||||
nsMappedAttributes* Clone(bool aWillAddAttr);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING_WITH_DESTROY(nsMappedAttributes, LastRelease())
|
||||
|
||||
void SetAndSwapAttr(nsAtom* aAttrName, nsAttrValue& aValue,
|
||||
bool* aValueWasSet);
|
||||
const nsAttrValue* GetAttr(const nsAtom* aAttrName) const;
|
||||
const nsAttrValue* GetAttr(const nsAString& aAttrName) const;
|
||||
|
||||
uint32_t Count() const { return mAttrCount; }
|
||||
|
||||
bool Equals(const nsMappedAttributes* aAttributes) const;
|
||||
PLDHashNumber HashValue() const;
|
||||
|
||||
void DropAttributeStylesReference() { mAttrStyles = nullptr; }
|
||||
void SetAttributeStyles(mozilla::AttributeStyles*);
|
||||
mozilla::AttributeStyles* GetAttributeStyles() { return mAttrStyles; }
|
||||
|
||||
void SetRuleMapper(nsMapRuleToAttributesFunc aRuleMapper) {
|
||||
mRuleMapper = aRuleMapper;
|
||||
}
|
||||
|
||||
auto Attrs() const {
|
||||
return mozilla::Span<const InternalAttr>{mBuffer, mAttrCount};
|
||||
}
|
||||
auto Attrs() { return mozilla::Span<InternalAttr>{mBuffer, mAttrCount}; }
|
||||
const nsAttrName* NameAt(uint32_t aPos) const {
|
||||
NS_ASSERTION(aPos < mAttrCount, "out-of-bounds");
|
||||
return &Attrs()[aPos].mName;
|
||||
}
|
||||
const nsAttrValue* AttrAt(uint32_t aPos) const {
|
||||
NS_ASSERTION(aPos < mAttrCount, "out-of-bounds");
|
||||
return &Attrs()[aPos].mValue;
|
||||
}
|
||||
// Remove the attr at position aPos. The value of the attr is placed in
|
||||
// aValue; any value that was already in aValue is destroyed.
|
||||
void RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue);
|
||||
const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
|
||||
int32_t IndexOfAttr(const nsAtom* aLocalName) const;
|
||||
|
||||
// Apply the contained mapper to the contained set of servo rules,
|
||||
// unless the servo rules have already been initialized.
|
||||
void LazilyResolveServoDeclaration(mozilla::dom::Document* aDocument);
|
||||
|
||||
// Obtain the contained servo declaration block
|
||||
// May return null if called before the inner block
|
||||
// has been (lazily) resolved
|
||||
const mozilla::StyleLockedDeclarationBlock* GetServoStyle() const {
|
||||
return mServoStyle;
|
||||
}
|
||||
|
||||
void ClearServoStyle() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mServoStyle = nullptr;
|
||||
}
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
static void Shutdown();
|
||||
|
||||
private:
|
||||
void LastRelease();
|
||||
|
||||
nsMappedAttributes(const nsMappedAttributes& aCopy);
|
||||
~nsMappedAttributes();
|
||||
|
||||
uint16_t mAttrCount;
|
||||
#ifdef DEBUG
|
||||
uint16_t mBufferSize;
|
||||
#endif
|
||||
mozilla::AttributeStyles* mAttrStyles; // weak
|
||||
nsMapRuleToAttributesFunc mRuleMapper;
|
||||
RefPtr<mozilla::StyleLockedDeclarationBlock> mServoStyle;
|
||||
InternalAttr mBuffer[0];
|
||||
|
||||
static bool sShuttingDown;
|
||||
|
||||
// We're caching some memory to avoid trashing the allocator.
|
||||
// The memory stored at index N can hold N attribute values.
|
||||
static nsTArray<void*>* sCachedMappedAttributeAllocations;
|
||||
};
|
||||
|
||||
#endif /* nsMappedAttributes_h___ */
|
|
@ -228,7 +228,7 @@ function testHtmlSerializer_1 () {
|
|||
encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw);
|
||||
encoder.setNode(node);
|
||||
out = encoder.encodeToString();
|
||||
expected = '<hr id="shortattr6" noshade="noshade">';
|
||||
expected = '<hr noshade="noshade" id="shortattr6">';
|
||||
is(out, expected, "test short attr #6");
|
||||
|
||||
node = document.getElementById('shortattr7');
|
||||
|
|
|
@ -6,10 +6,9 @@
|
|||
|
||||
#include "mozilla/dom/HTMLBRElement.h"
|
||||
#include "mozilla/dom/HTMLBRElementBinding.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(BR)
|
||||
|
||||
|
@ -42,14 +41,14 @@ bool HTMLBRElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
aMaybeScriptedPrincipal, aResult);
|
||||
}
|
||||
|
||||
void HTMLBRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_clear)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::clear);
|
||||
if (value && value->Type() == nsAttrValue::eEnum)
|
||||
aDecls.SetKeywordValue(eCSSProperty_clear, value->GetEnumValue());
|
||||
void HTMLBRElement::MapAttributesIntoRule(MappedDeclarationsBuilder& aBuilder) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_clear)) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::clear);
|
||||
if (value && value->Type() == nsAttrValue::eEnum) {
|
||||
aBuilder.SetKeywordValue(eCSSProperty_clear, value->GetEnumValue());
|
||||
}
|
||||
}
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -65,8 +65,7 @@ class HTMLBRElement final : public nsGenericHTMLElement {
|
|||
private:
|
||||
virtual ~HTMLBRElement();
|
||||
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "mozilla/AttributeStyles.h"
|
||||
#include "mozilla/EditorBase.h"
|
||||
#include "mozilla/HTMLEditor.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/TextEditor.h"
|
||||
#include "mozilla/dom/BindContext.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
|
@ -20,7 +20,6 @@
|
|||
#include "nsPresContext.h"
|
||||
#include "DocumentInlines.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
|
||||
|
@ -66,7 +65,7 @@ bool HTMLBodyElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLBodyElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// This is the one place where we try to set the same property
|
||||
// multiple times in presentation attributes. Servo does not support
|
||||
// querying if a property is set (because that is O(n) behavior
|
||||
|
@ -84,143 +83,143 @@ void HTMLBodyElement::MapAttributesIntoRule(
|
|||
|
||||
const nsAttrValue* value;
|
||||
// if marginwidth/marginheight are set, reflect them as 'margin'
|
||||
value = aAttributes->GetAttr(nsGkAtoms::marginwidth);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::marginwidth);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
bodyMarginWidth = value->GetIntegerValue();
|
||||
if (bodyMarginWidth < 0) {
|
||||
bodyMarginWidth = 0;
|
||||
}
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_left,
|
||||
(float)bodyMarginWidth);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_right,
|
||||
(float)bodyMarginWidth);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_left,
|
||||
(float)bodyMarginWidth);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_right,
|
||||
(float)bodyMarginWidth);
|
||||
}
|
||||
|
||||
value = aAttributes->GetAttr(nsGkAtoms::marginheight);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::marginheight);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
bodyMarginHeight = value->GetIntegerValue();
|
||||
if (bodyMarginHeight < 0) {
|
||||
bodyMarginHeight = 0;
|
||||
}
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_top,
|
||||
(float)bodyMarginHeight);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_bottom,
|
||||
(float)bodyMarginHeight);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_top,
|
||||
(float)bodyMarginHeight);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_bottom,
|
||||
(float)bodyMarginHeight);
|
||||
}
|
||||
|
||||
// topmargin (IE-attribute)
|
||||
if (bodyMarginHeight == -1) {
|
||||
value = aAttributes->GetAttr(nsGkAtoms::topmargin);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::topmargin);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
bodyTopMargin = value->GetIntegerValue();
|
||||
if (bodyTopMargin < 0) {
|
||||
bodyTopMargin = 0;
|
||||
}
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_top,
|
||||
(float)bodyTopMargin);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_top,
|
||||
(float)bodyTopMargin);
|
||||
}
|
||||
}
|
||||
// bottommargin (IE-attribute)
|
||||
|
||||
if (bodyMarginHeight == -1) {
|
||||
value = aAttributes->GetAttr(nsGkAtoms::bottommargin);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::bottommargin);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
bodyBottomMargin = value->GetIntegerValue();
|
||||
if (bodyBottomMargin < 0) {
|
||||
bodyBottomMargin = 0;
|
||||
}
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_bottom,
|
||||
(float)bodyBottomMargin);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_bottom,
|
||||
(float)bodyBottomMargin);
|
||||
}
|
||||
}
|
||||
|
||||
// leftmargin (IE-attribute)
|
||||
if (bodyMarginWidth == -1) {
|
||||
value = aAttributes->GetAttr(nsGkAtoms::leftmargin);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::leftmargin);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
bodyLeftMargin = value->GetIntegerValue();
|
||||
if (bodyLeftMargin < 0) {
|
||||
bodyLeftMargin = 0;
|
||||
}
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_left,
|
||||
(float)bodyLeftMargin);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_left,
|
||||
(float)bodyLeftMargin);
|
||||
}
|
||||
}
|
||||
// rightmargin (IE-attribute)
|
||||
if (bodyMarginWidth == -1) {
|
||||
value = aAttributes->GetAttr(nsGkAtoms::rightmargin);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::rightmargin);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
bodyRightMargin = value->GetIntegerValue();
|
||||
if (bodyRightMargin < 0) {
|
||||
bodyRightMargin = 0;
|
||||
}
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_right,
|
||||
(float)bodyRightMargin);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_right,
|
||||
(float)bodyRightMargin);
|
||||
}
|
||||
}
|
||||
|
||||
// if marginwidth or marginheight is set in the <frame> and not set in the
|
||||
// <body> reflect them as margin in the <body>
|
||||
if (bodyMarginWidth == -1 || bodyMarginHeight == -1) {
|
||||
if (nsDocShell* ds = nsDocShell::Cast(aDecls.Document()->GetDocShell())) {
|
||||
if (nsDocShell* ds = nsDocShell::Cast(aBuilder.Document().GetDocShell())) {
|
||||
CSSIntSize margins = ds->GetFrameMargins();
|
||||
int32_t frameMarginWidth = margins.width;
|
||||
int32_t frameMarginHeight = margins.height;
|
||||
|
||||
if (bodyMarginWidth == -1 && frameMarginWidth >= 0) {
|
||||
if (bodyLeftMargin == -1) {
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_left,
|
||||
(float)frameMarginWidth);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_left,
|
||||
(float)frameMarginWidth);
|
||||
}
|
||||
if (bodyRightMargin == -1) {
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_right,
|
||||
(float)frameMarginWidth);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_right,
|
||||
(float)frameMarginWidth);
|
||||
}
|
||||
}
|
||||
|
||||
if (bodyMarginHeight == -1 && frameMarginHeight >= 0) {
|
||||
if (bodyTopMargin == -1) {
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_top,
|
||||
(float)frameMarginHeight);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_top,
|
||||
(float)frameMarginHeight);
|
||||
}
|
||||
if (bodyBottomMargin == -1) {
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_bottom,
|
||||
(float)frameMarginHeight);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_bottom,
|
||||
(float)frameMarginHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When display if first asked for, go ahead and get our colors set up.
|
||||
if (AttributeStyles* attrStyles = aDecls.Document()->GetAttributeStyles()) {
|
||||
if (AttributeStyles* attrStyles = aBuilder.Document().GetAttributeStyles()) {
|
||||
nscolor color;
|
||||
value = aAttributes->GetAttr(nsGkAtoms::link);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::link);
|
||||
if (value && value->GetColorValue(color)) {
|
||||
attrStyles->SetLinkColor(color);
|
||||
}
|
||||
|
||||
value = aAttributes->GetAttr(nsGkAtoms::alink);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::alink);
|
||||
if (value && value->GetColorValue(color)) {
|
||||
attrStyles->SetActiveLinkColor(color);
|
||||
}
|
||||
|
||||
value = aAttributes->GetAttr(nsGkAtoms::vlink);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::vlink);
|
||||
if (value && value->GetColorValue(color)) {
|
||||
attrStyles->SetVisitedLinkColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_color)) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_color)) {
|
||||
// color: color
|
||||
nscolor color;
|
||||
value = aAttributes->GetAttr(nsGkAtoms::text);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::text);
|
||||
if (value && value->GetColorValue(color)) {
|
||||
aDecls.SetColorValue(eCSSProperty_color, color);
|
||||
aBuilder.SetColorValue(eCSSProperty_color, color);
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapBackgroundAttributesInto(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
nsMapRuleToAttributesFunc HTMLBodyElement::GetAttributeMappingFunction() const {
|
||||
|
@ -281,26 +280,17 @@ bool HTMLBodyElement::IsEventAttributeNameInternal(nsAtom* aName) {
|
|||
}
|
||||
|
||||
nsresult HTMLBodyElement::BindToTree(BindContext& aContext, nsINode& aParent) {
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aContext, aParent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return mAttrs.ForceMapped(this);
|
||||
mAttrs.MarkAsPendingPresAttributeEvaluation();
|
||||
return nsGenericHTMLElement::BindToTree(aContext, aParent);
|
||||
}
|
||||
|
||||
void HTMLBodyElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue,
|
||||
nsIPrincipal* aSubjectPrincipal,
|
||||
bool aNotify) {
|
||||
nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue, aOldValue,
|
||||
aSubjectPrincipal, aNotify);
|
||||
// If the last mapped attribute was removed, don't clear the
|
||||
// nsMappedAttributes, our style can still depend on the containing frame
|
||||
// element.
|
||||
//
|
||||
// FIXME(emilio, bug 1839333): Is this true? We don't store containing frame
|
||||
// stuff in nsMappedAttributes / AttributeStyles, maybe we can remove this?
|
||||
if (!aValue && IsAttributeMapped(aName)) {
|
||||
Unused << mAttrs.ForceMapped(this);
|
||||
void HTMLBodyElement::FrameMarginsChanged() {
|
||||
MOZ_ASSERT(IsInComposedDoc());
|
||||
if (IsPendingMappedAttributeEvaluation()) {
|
||||
return;
|
||||
}
|
||||
if (mAttrs.MarkAsPendingPresAttributeEvaluation()) {
|
||||
OwnerDoc()->ScheduleForPresAttrEvaluation(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,37 +88,27 @@ class HTMLBodyElement final : public nsGenericHTMLElement {
|
|||
SetHTMLAttr(nsGkAtoms::background, aBackground, aError);
|
||||
}
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
virtual already_AddRefed<EditorBase> GetAssociatedEditor() override;
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
already_AddRefed<EditorBase> GetAssociatedEditor() override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
virtual bool IsEventAttributeNameInternal(nsAtom* aName) override;
|
||||
bool IsEventAttributeNameInternal(nsAtom* aName) override;
|
||||
nsresult BindToTree(BindContext&, nsINode& aParent) override;
|
||||
|
||||
virtual nsresult BindToTree(BindContext&, nsINode& aParent) override;
|
||||
/**
|
||||
* Called when an attribute has just been changed
|
||||
*/
|
||||
virtual void AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue,
|
||||
nsIPrincipal* aSubjectPrincipal,
|
||||
bool aNotify) override;
|
||||
void FrameMarginsChanged();
|
||||
|
||||
protected:
|
||||
virtual ~HTMLBodyElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -725,9 +725,9 @@ nsChangeHint HTMLCanvasElement::GetAttributeChangeHint(const nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLCanvasElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MapAspectRatioInto(aAttributes, aDecls);
|
||||
MapCommonAttributesInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
MapAspectRatioInto(aBuilder);
|
||||
MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
nsMapRuleToAttributesFunc HTMLCanvasElement::GetAttributeMappingFunction()
|
||||
|
|
|
@ -266,8 +266,7 @@ class HTMLCanvasElement final : public nsGenericHTMLElement,
|
|||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsresult CopyInnerTo(HTMLCanvasElement* aDest);
|
||||
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
|
||||
/*
|
||||
* Helpers called by various users of Canvas
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "HTMLDivElement.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "mozilla/dom/HTMLDivElementBinding.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Div)
|
||||
|
@ -36,9 +35,9 @@ bool HTMLDivElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLDivElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
MapDivAlignAttributeInto(aBuilder);
|
||||
MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -24,24 +24,21 @@ class HTMLDivElement final : public nsGenericHTMLElement {
|
|||
SetHTMLAttr(nsGkAtoms::align, aAlign, aError);
|
||||
}
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
protected:
|
||||
virtual ~HTMLDivElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
# include "mozilla/EventDispatcher.h"
|
||||
# include "mozilla/dom/Event.h"
|
||||
#endif
|
||||
#include "mozilla/dom/HTMLObjectElement.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Embed)
|
||||
|
||||
|
@ -179,24 +178,22 @@ bool HTMLEmbedElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
aMaybeScriptedPrincipal, aResult);
|
||||
}
|
||||
|
||||
static void MapAttributesIntoRuleBase(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations& aDecls) {
|
||||
nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aDecls);
|
||||
static void MapAttributesIntoRuleBase(MappedDeclarationsBuilder& aBuilder) {
|
||||
nsGenericHTMLElement::MapImageMarginAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aBuilder);
|
||||
nsGenericHTMLElement::MapImageAlignAttributeInto(aBuilder);
|
||||
}
|
||||
|
||||
static void MapAttributesIntoRuleExceptHidden(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MapAttributesIntoRuleBase(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden(aAttributes,
|
||||
aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
MapAttributesIntoRuleBase(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden(aBuilder);
|
||||
}
|
||||
|
||||
void HTMLEmbedElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MapAttributesIntoRuleBase(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
MapAttributesIntoRuleBase(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -33,28 +33,27 @@ class HTMLEmbedElement final : public nsGenericHTMLElement,
|
|||
}
|
||||
|
||||
// EventTarget
|
||||
virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
|
||||
void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
|
||||
|
||||
virtual nsresult BindToTree(BindContext&, nsINode& aParent) override;
|
||||
virtual void UnbindFromTree(bool aNullParent = true) override;
|
||||
nsresult BindToTree(BindContext&, nsINode& aParent) override;
|
||||
void UnbindFromTree(bool aNullParent = true) override;
|
||||
|
||||
virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
|
||||
int32_t* aTabIndex) override;
|
||||
bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
|
||||
int32_t* aTabIndex) override;
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
virtual ElementState IntrinsicState() const override;
|
||||
virtual void DestroyContent() override;
|
||||
ElementState IntrinsicState() const override;
|
||||
void DestroyContent() override;
|
||||
|
||||
// nsObjectLoadingContent
|
||||
virtual uint32_t GetCapabilities() const override;
|
||||
uint32_t GetCapabilities() const override;
|
||||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
nsresult CopyInnerTo(HTMLEmbedElement* aDest);
|
||||
|
||||
|
@ -106,25 +105,21 @@ class HTMLEmbedElement final : public nsGenericHTMLElement,
|
|||
// Override for nsImageLoadingContent.
|
||||
nsIContent* AsContent() override { return this; }
|
||||
|
||||
virtual void AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue,
|
||||
nsIPrincipal* aSubjectPrincipal,
|
||||
bool aNotify) override;
|
||||
virtual void OnAttrSetButNotChanged(int32_t aNamespaceID, nsAtom* aName,
|
||||
const nsAttrValueOrString& aValue,
|
||||
bool aNotify) override;
|
||||
void AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
||||
const nsAttrValue* aValue, const nsAttrValue* aOldValue,
|
||||
nsIPrincipal* aSubjectPrincipal, bool aNotify) override;
|
||||
void OnAttrSetButNotChanged(int32_t aNamespaceID, nsAtom* aName,
|
||||
const nsAttrValueOrString& aValue,
|
||||
bool aNotify) override;
|
||||
|
||||
private:
|
||||
~HTMLEmbedElement();
|
||||
|
||||
nsContentPolicyType GetContentPolicyType() const override;
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
|
||||
/**
|
||||
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
#include "HTMLFontElement.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/HTMLFontElementBinding.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Font)
|
||||
|
@ -48,41 +47,43 @@ bool HTMLFontElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLFontElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// face: string list
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_font_family)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::face);
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_font_family)) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::face);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
!value->IsEmptyString()) {
|
||||
aDecls.SetFontFamily(NS_ConvertUTF16toUTF8(value->GetStringValue()));
|
||||
aBuilder.SetFontFamily(NS_ConvertUTF16toUTF8(value->GetStringValue()));
|
||||
}
|
||||
}
|
||||
// size: int
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_font_size)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::size);
|
||||
if (value && value->Type() == nsAttrValue::eInteger)
|
||||
aDecls.SetKeywordValue(eCSSProperty_font_size, value->GetIntegerValue());
|
||||
}
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_color)) {
|
||||
// color: color
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::color);
|
||||
nscolor color;
|
||||
if (value && value->GetColorValue(color)) {
|
||||
aDecls.SetColorValue(eCSSProperty_color, color);
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_font_size)) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::size);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
aBuilder.SetKeywordValue(eCSSProperty_font_size,
|
||||
value->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
if (aDecls.Document()->GetCompatibilityMode() == eCompatibility_NavQuirks) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_color)) {
|
||||
// color: color
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::color);
|
||||
nscolor color;
|
||||
if (value && value->GetColorValue(color)) {
|
||||
aBuilder.SetColorValue(eCSSProperty_color, color);
|
||||
}
|
||||
}
|
||||
if (aBuilder.Document().GetCompatibilityMode() == eCompatibility_NavQuirks) {
|
||||
// Make <a><font color="red">text</font></a> give the text a red underline
|
||||
// in quirks mode. The StyleTextDecorationLine_COLOR_OVERRIDE flag only
|
||||
// affects quirks mode rendering.
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::color);
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::color);
|
||||
nscolor color;
|
||||
if (value && value->GetColorValue(color)) {
|
||||
aDecls.SetTextDecorationColorOverride();
|
||||
aBuilder.SetTextDecorationColorOverride();
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -29,24 +29,21 @@ class HTMLFontElement final : public nsGenericHTMLElement {
|
|||
SetHTMLAttr(nsGkAtoms::size, aSize, aError);
|
||||
}
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
protected:
|
||||
virtual ~HTMLFontElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -28,11 +28,11 @@ class HTMLFrameElement final : public nsGenericHTMLFrameElement {
|
|||
NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLFrameElement, frame)
|
||||
|
||||
// nsIContent
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
// WebIDL API
|
||||
void GetFrameBorder(DOMString& aFrameBorder) const {
|
||||
|
@ -92,12 +92,7 @@ class HTMLFrameElement final : public nsGenericHTMLFrameElement {
|
|||
protected:
|
||||
virtual ~HTMLFrameElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(HR)
|
||||
|
||||
|
@ -52,56 +52,55 @@ bool HTMLHRElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
aMaybeScriptedPrincipal, aResult);
|
||||
}
|
||||
|
||||
void HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations& aDecls) {
|
||||
void HTMLHRElement::MapAttributesIntoRule(MappedDeclarationsBuilder& aBuilder) {
|
||||
bool noshade = false;
|
||||
|
||||
const nsAttrValue* colorValue = aAttributes->GetAttr(nsGkAtoms::color);
|
||||
const nsAttrValue* colorValue = aBuilder.GetAttr(nsGkAtoms::color);
|
||||
nscolor color;
|
||||
bool colorIsSet = colorValue && colorValue->GetColorValue(color);
|
||||
|
||||
if (colorIsSet) {
|
||||
noshade = true;
|
||||
} else {
|
||||
noshade = !!aAttributes->GetAttr(nsGkAtoms::noshade);
|
||||
noshade = !!aBuilder.GetAttr(nsGkAtoms::noshade);
|
||||
}
|
||||
|
||||
// align: enum
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::align);
|
||||
if (value && value->Type() == nsAttrValue::eEnum) {
|
||||
// Map align attribute into auto side margins
|
||||
switch (StyleTextAlign(value->GetEnumValue())) {
|
||||
case StyleTextAlign::Left:
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_left, 0.0f);
|
||||
aDecls.SetAutoValueIfUnset(eCSSProperty_margin_right);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_left, 0.0f);
|
||||
aBuilder.SetAutoValueIfUnset(eCSSProperty_margin_right);
|
||||
break;
|
||||
case StyleTextAlign::Right:
|
||||
aDecls.SetAutoValueIfUnset(eCSSProperty_margin_left);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_right, 0.0f);
|
||||
aBuilder.SetAutoValueIfUnset(eCSSProperty_margin_left);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_right, 0.0f);
|
||||
break;
|
||||
case StyleTextAlign::Center:
|
||||
aDecls.SetAutoValueIfUnset(eCSSProperty_margin_left);
|
||||
aDecls.SetAutoValueIfUnset(eCSSProperty_margin_right);
|
||||
aBuilder.SetAutoValueIfUnset(eCSSProperty_margin_left);
|
||||
aBuilder.SetAutoValueIfUnset(eCSSProperty_margin_right);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown <hr align> value");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_height)) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_height)) {
|
||||
// size: integer
|
||||
if (noshade) {
|
||||
// noshade case: size is set using the border
|
||||
aDecls.SetAutoValue(eCSSProperty_height);
|
||||
aBuilder.SetAutoValue(eCSSProperty_height);
|
||||
} else {
|
||||
// normal case
|
||||
// the height includes the top and bottom borders that are initially 1px.
|
||||
// for size=1, html.css has a special case rule that makes this work by
|
||||
// removing all but the top border.
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::size);
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::size);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
aDecls.SetPixelValue(eCSSProperty_height,
|
||||
(float)value->GetIntegerValue());
|
||||
aBuilder.SetPixelValue(eCSSProperty_height,
|
||||
(float)value->GetIntegerValue());
|
||||
} // else use default value from html.css
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +111,7 @@ void HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
|||
// if a size is set, use half of it per side, otherwise, use 1px per side
|
||||
float sizePerSide;
|
||||
bool allSides = true;
|
||||
value = aAttributes->GetAttr(nsGkAtoms::size);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::size);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
sizePerSide = (float)value->GetIntegerValue() / 2.0f;
|
||||
if (sizePerSide < 1.0f) {
|
||||
|
@ -125,24 +124,27 @@ void HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
|||
} else {
|
||||
sizePerSide = 1.0f; // default to a 2px high line
|
||||
}
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_top_width, sizePerSide);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_top_width, sizePerSide);
|
||||
if (allSides) {
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_right_width, sizePerSide);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_bottom_width,
|
||||
sizePerSide);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_left_width, sizePerSide);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_right_width,
|
||||
sizePerSide);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_bottom_width,
|
||||
sizePerSide);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_left_width,
|
||||
sizePerSide);
|
||||
}
|
||||
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_border_top_style))
|
||||
aDecls.SetKeywordValue(eCSSProperty_border_top_style,
|
||||
StyleBorderStyle::Solid);
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_border_top_style)) {
|
||||
aBuilder.SetKeywordValue(eCSSProperty_border_top_style,
|
||||
StyleBorderStyle::Solid);
|
||||
}
|
||||
if (allSides) {
|
||||
aDecls.SetKeywordValueIfUnset(eCSSProperty_border_right_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aDecls.SetKeywordValueIfUnset(eCSSProperty_border_bottom_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aDecls.SetKeywordValueIfUnset(eCSSProperty_border_left_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aBuilder.SetKeywordValueIfUnset(eCSSProperty_border_right_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aBuilder.SetKeywordValueIfUnset(eCSSProperty_border_bottom_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aBuilder.SetKeywordValueIfUnset(eCSSProperty_border_left_style,
|
||||
StyleBorderStyle::Solid);
|
||||
|
||||
// If it would be noticeable, set the border radius to
|
||||
// 10000px on all corners; this triggers the clamping to make
|
||||
|
@ -151,18 +153,17 @@ void HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
|||
for (const nsCSSPropertyID* props =
|
||||
nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_radius);
|
||||
*props != eCSSProperty_UNKNOWN; ++props) {
|
||||
aDecls.SetPixelValueIfUnset(*props, 10000.0f);
|
||||
aBuilder.SetPixelValueIfUnset(*props, 10000.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
// color: a color
|
||||
// (we got the color attribute earlier)
|
||||
if (colorIsSet) {
|
||||
aDecls.SetColorValueIfUnset(eCSSProperty_color, color);
|
||||
aBuilder.SetColorValueIfUnset(eCSSProperty_color, color);
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapWidthAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
MapWidthAttributeInto(aBuilder);
|
||||
MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
#define mozilla_dom_HTMLHRElement_h
|
||||
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
|
@ -20,14 +18,13 @@ class HTMLHRElement final : public nsGenericHTMLElement {
|
|||
// nsISupports
|
||||
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLHRElement, nsGenericHTMLElement)
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
// WebIDL API
|
||||
void GetAlign(nsAString& aValue) const {
|
||||
|
@ -66,12 +63,10 @@ class HTMLHRElement final : public nsGenericHTMLElement {
|
|||
protected:
|
||||
virtual ~HTMLHRElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -7,12 +7,8 @@
|
|||
#include "mozilla/dom/HTMLHeadingElement.h"
|
||||
#include "mozilla/dom/HTMLHeadingElementBinding.h"
|
||||
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/StaticPrefs_accessibility.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Heading)
|
||||
|
||||
|
@ -41,9 +37,9 @@ bool HTMLHeadingElement::ParseAttribute(int32_t aNamespaceID,
|
|||
}
|
||||
|
||||
void HTMLHeadingElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -64,8 +64,7 @@ class HTMLHeadingElement final : public nsGenericHTMLElement {
|
|||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -9,13 +9,11 @@
|
|||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/HTMLIFrameElementBinding.h"
|
||||
#include "mozilla/dom/FeaturePolicy.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsError.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
@ -108,25 +106,25 @@ bool HTMLIFrameElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLIFrameElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// frameborder: 0 | 1 (| NO | YES in quirks mode)
|
||||
// If frameborder is 0 or No, set border to 0
|
||||
// else leave it as the value set in html.css
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::frameborder);
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::frameborder);
|
||||
if (value && value->Type() == nsAttrValue::eEnum) {
|
||||
auto frameborder = static_cast<FrameBorderProperty>(value->GetEnumValue());
|
||||
if (FrameBorderProperty::No == frameborder ||
|
||||
FrameBorderProperty::Zero == frameborder) {
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_top_width, 0.0f);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_right_width, 0.0f);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_bottom_width, 0.0f);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_left_width, 0.0f);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_top_width, 0.0f);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_right_width, 0.0f);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_bottom_width, 0.0f);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_left_width, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aBuilder);
|
||||
nsGenericHTMLElement::MapImageAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -173,8 +173,7 @@ class HTMLIFrameElement final : public nsGenericHTMLFrameElement {
|
|||
bool aNotify) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
|
||||
static const DOMTokenListSupportedToken sSupportedSandboxTokens[];
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsSize.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsImageFrame.h"
|
||||
|
@ -43,7 +42,7 @@
|
|||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RestyleManager.h"
|
||||
|
||||
|
@ -258,12 +257,12 @@ bool HTMLImageElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLImageElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MapImageAlignAttributeInto(aAttributes, aDecls);
|
||||
MapImageBorderAttributeInto(aAttributes, aDecls);
|
||||
MapImageMarginAttributeInto(aAttributes, aDecls);
|
||||
MapImageSizeAttributesInto(aAttributes, aDecls, MapAspectRatio::Yes);
|
||||
MapCommonAttributesInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
MapImageAlignAttributeInto(aBuilder);
|
||||
MapImageBorderAttributeInto(aBuilder);
|
||||
MapImageMarginAttributeInto(aBuilder);
|
||||
MapImageSizeAttributesInto(aBuilder, MapAspectRatio::Yes);
|
||||
MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
nsChangeHint HTMLImageElement::GetAttributeChangeHint(const nsAtom* aAttribute,
|
||||
|
@ -1343,15 +1342,14 @@ void HTMLImageElement::StopLazyLoading(StartLoading aStartLoading) {
|
|||
}
|
||||
}
|
||||
|
||||
const nsMappedAttributes* HTMLImageElement::GetMappedAttributesFromSource()
|
||||
const {
|
||||
if (!IsInPicture() || !mResponsiveSelector ||
|
||||
!mResponsiveSelector->Content()) {
|
||||
const StyleLockedDeclarationBlock*
|
||||
HTMLImageElement::GetMappedAttributesFromSource() const {
|
||||
if (!IsInPicture() || !mResponsiveSelector) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto* source =
|
||||
HTMLSourceElement::FromNode(mResponsiveSelector->Content());
|
||||
HTMLSourceElement::FromNodeOrNull(mResponsiveSelector->Content());
|
||||
if (!source) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ class HTMLImageElement final : public nsGenericHTMLElement,
|
|||
|
||||
// This is used when restyling, for retrieving the extra style from the source
|
||||
// element.
|
||||
const nsMappedAttributes* GetMappedAttributesFromSource() const;
|
||||
const StyleLockedDeclarationBlock* GetMappedAttributesFromSource() const;
|
||||
|
||||
protected:
|
||||
virtual ~HTMLImageElement();
|
||||
|
@ -380,8 +380,7 @@ class HTMLImageElement final : public nsGenericHTMLElement,
|
|||
private:
|
||||
bool SourceElementMatches(Element* aSourceElement);
|
||||
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
/**
|
||||
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||
* It will not be called if the value is being unset.
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/HTMLDataListElement.h"
|
||||
|
@ -75,7 +74,7 @@
|
|||
|
||||
#include "mozilla/ContentEvents.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/InternalMutationEvent.h"
|
||||
#include "mozilla/TextControlState.h"
|
||||
#include "mozilla/TextEditor.h"
|
||||
|
@ -4469,30 +4468,32 @@ void HTMLInputElement::HandleTypeChange(FormControlType aNewType,
|
|||
RecomputeDirectionality(this, aNotify);
|
||||
}
|
||||
|
||||
if (oldType == FormControlType::InputImage) {
|
||||
// We're no longer an image input. Cancel our image requests, if we have
|
||||
// any.
|
||||
CancelImageRequests(aNotify);
|
||||
|
||||
// And we should update our mapped attribute mapping function.
|
||||
mAttrs.UpdateMappedAttrRuleMapper(*this);
|
||||
} else if (mType == FormControlType::InputImage) {
|
||||
if (aNotify) {
|
||||
// We just got switched to be an image input; we should see
|
||||
// whether we have an image to load;
|
||||
if (oldType == FormControlType::InputImage ||
|
||||
mType == FormControlType::InputImage) {
|
||||
if (oldType == FormControlType::InputImage) {
|
||||
// We're no longer an image input. Cancel our image requests, if we have
|
||||
// any.
|
||||
CancelImageRequests(aNotify);
|
||||
} else if (aNotify) {
|
||||
// We just got switched to be an image input; we should see whether we
|
||||
// have an image to load;
|
||||
nsAutoString src;
|
||||
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
|
||||
if (GetAttr(nsGkAtoms::src, src)) {
|
||||
// Mark channel as urgent-start before load image if the image load is
|
||||
// initaiated by a user interaction.
|
||||
// initiated by a user interaction.
|
||||
mUseUrgentStartForChannel = UserActivation::IsHandlingUserInput();
|
||||
|
||||
LoadImage(src, false, aNotify, eImageLoadType_Normal,
|
||||
mSrcTriggeringPrincipal);
|
||||
}
|
||||
}
|
||||
|
||||
// And we should update our mapped attribute mapping function.
|
||||
mAttrs.UpdateMappedAttrRuleMapper(*this);
|
||||
// We should update our mapped attribute mapping function.
|
||||
if (mAttrs.HasAttrs() && !mAttrs.IsPendingMappedAttributeEvaluation()) {
|
||||
mAttrs.InfallibleMarkAsPendingPresAttributeEvaluation();
|
||||
if (auto* doc = GetComposedDoc()) {
|
||||
doc->ScheduleForPresAttrEvaluation(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mType == FormControlType::InputPassword && IsInComposedDoc()) {
|
||||
|
@ -5248,19 +5249,17 @@ bool HTMLInputElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLInputElement::ImageInputMapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
nsGenericHTMLFormControlElementWithState::MapImageBorderAttributeInto(
|
||||
aAttributes, aDecls);
|
||||
aBuilder);
|
||||
nsGenericHTMLFormControlElementWithState::MapImageMarginAttributeInto(
|
||||
aAttributes, aDecls);
|
||||
aBuilder);
|
||||
nsGenericHTMLFormControlElementWithState::MapImageSizeAttributesInto(
|
||||
aAttributes, aDecls, MapAspectRatio::Yes);
|
||||
aBuilder, MapAspectRatio::Yes);
|
||||
// Images treat align as "float"
|
||||
nsGenericHTMLFormControlElementWithState::MapImageAlignAttributeInto(
|
||||
aAttributes, aDecls);
|
||||
|
||||
nsGenericHTMLFormControlElementWithState::MapCommonAttributesInto(aAttributes,
|
||||
aDecls);
|
||||
aBuilder);
|
||||
nsGenericHTMLFormControlElementWithState::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
nsChangeHint HTMLInputElement::GetAttributeChangeHint(const nsAtom* aAttribute,
|
||||
|
|
|
@ -1565,8 +1565,7 @@ class HTMLInputElement final : public TextControlElement,
|
|||
bool mHasPatternAttribute : 1;
|
||||
|
||||
private:
|
||||
static void ImageInputMapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations&);
|
||||
static void ImageInputMapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
|
||||
/**
|
||||
* Returns true if this input's type will fire a DOM "change" event when it
|
||||
|
|
|
@ -7,11 +7,10 @@
|
|||
#include "mozilla/dom/HTMLLIElement.h"
|
||||
#include "mozilla/dom/HTMLLIElementBinding.h"
|
||||
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(LI)
|
||||
|
||||
|
@ -53,25 +52,25 @@ bool HTMLLIElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
aMaybeScriptedPrincipal, aResult);
|
||||
}
|
||||
|
||||
void HTMLLIElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_list_style_type)) {
|
||||
void HTMLLIElement::MapAttributesIntoRule(MappedDeclarationsBuilder& aBuilder) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_list_style_type)) {
|
||||
// type: enum
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::type);
|
||||
if (value && value->Type() == nsAttrValue::eEnum)
|
||||
aDecls.SetKeywordValue(eCSSProperty_list_style_type,
|
||||
value->GetEnumValue());
|
||||
}
|
||||
|
||||
// Map <li value=INTEGER> to 'counter-set: list-item INTEGER'.
|
||||
const nsAttrValue* attrVal = aAttributes->GetAttr(nsGkAtoms::value);
|
||||
if (attrVal && attrVal->Type() == nsAttrValue::eInteger) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_counter_set)) {
|
||||
aDecls.SetCounterSetListItem(attrVal->GetIntegerValue());
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::type);
|
||||
if (value && value->Type() == nsAttrValue::eEnum) {
|
||||
aBuilder.SetKeywordValue(eCSSProperty_list_style_type,
|
||||
value->GetEnumValue());
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
// Map <li value=INTEGER> to 'counter-set: list-item INTEGER'.
|
||||
const nsAttrValue* attrVal = aBuilder.GetAttr(nsGkAtoms::value);
|
||||
if (attrVal && attrVal->Type() == nsAttrValue::eInteger) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_counter_set)) {
|
||||
aBuilder.SetCounterSetListItem(attrVal->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -21,14 +21,13 @@ class HTMLLIElement final : public nsGenericHTMLElement {
|
|||
// nsISupports
|
||||
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLLIElement, nsGenericHTMLElement)
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
// WebIDL API
|
||||
void GetType(DOMString& aType) { GetHTMLAttr(nsGkAtoms::type, aType); }
|
||||
|
@ -43,12 +42,10 @@ class HTMLLIElement final : public nsGenericHTMLElement {
|
|||
protected:
|
||||
virtual ~HTMLLIElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "mozilla/dom/HTMLMarqueeElement.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/dom/HTMLMarqueeElementBinding.h"
|
||||
#include "mozilla/dom/CustomEvent.h"
|
||||
|
@ -127,11 +126,11 @@ void HTMLMarqueeElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
|||
}
|
||||
|
||||
void HTMLMarqueeElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapBGColorInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
nsGenericHTMLElement::MapImageMarginAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
nsGenericHTMLElement::MapBGColorInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -104,11 +104,10 @@ class HTMLMarqueeElement final : public nsGenericHTMLElement {
|
|||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
virtual void AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
bool aNotify) override;
|
||||
void AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
||||
const nsAttrValue* aValue, const nsAttrValue* aOldValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
bool aNotify) override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
|
||||
|
@ -121,8 +120,7 @@ class HTMLMarqueeElement final : public nsGenericHTMLElement {
|
|||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
|
||||
void DispatchEventToShadowRoot(const nsAString& aEventTypeArg);
|
||||
};
|
||||
|
|
|
@ -232,16 +232,12 @@ bool HTMLObjectElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLObjectElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
nsGenericHTMLFormControlElement::MapImageAlignAttributeInto(aAttributes,
|
||||
aDecls);
|
||||
nsGenericHTMLFormControlElement::MapImageBorderAttributeInto(aAttributes,
|
||||
aDecls);
|
||||
nsGenericHTMLFormControlElement::MapImageMarginAttributeInto(aAttributes,
|
||||
aDecls);
|
||||
nsGenericHTMLFormControlElement::MapImageSizeAttributesInto(aAttributes,
|
||||
aDecls);
|
||||
nsGenericHTMLFormControlElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
MapImageAlignAttributeInto(aBuilder);
|
||||
MapImageBorderAttributeInto(aBuilder);
|
||||
MapImageMarginAttributeInto(aBuilder);
|
||||
MapImageSizeAttributesInto(aBuilder);
|
||||
MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -188,8 +188,7 @@ class HTMLObjectElement final : public nsGenericHTMLFormControlElement,
|
|||
JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
|
||||
/**
|
||||
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||
|
|
|
@ -5,26 +5,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/HTMLOptionsCollection.h"
|
||||
|
||||
#include "HTMLOptGroupElement.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/dom/HTMLFormSubmission.h"
|
||||
#include "mozilla/dom/HTMLOptionElement.h"
|
||||
#include "mozilla/dom/HTMLOptionsCollectionBinding.h"
|
||||
|
||||
#include "mozilla/dom/HTMLOptionElement.h"
|
||||
#include "mozilla/dom/HTMLSelectElement.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsError.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsIFormControlFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
#include "mozilla/dom/HTMLParagraphElement.h"
|
||||
#include "mozilla/dom/HTMLParagraphElementBinding.h"
|
||||
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Paragraph)
|
||||
|
||||
|
@ -33,9 +32,9 @@ bool HTMLParagraphElement::ParseAttribute(int32_t aNamespaceID,
|
|||
}
|
||||
|
||||
void HTMLParagraphElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -23,15 +23,14 @@ class HTMLParagraphElement final : public nsGenericHTMLElement {
|
|||
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLParagraphElement,
|
||||
nsGenericHTMLElement)
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
// WebIDL API
|
||||
void GetAlign(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::align, aValue); }
|
||||
|
@ -42,12 +41,10 @@ class HTMLParagraphElement final : public nsGenericHTMLElement {
|
|||
protected:
|
||||
virtual ~HTMLParagraphElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -7,11 +7,10 @@
|
|||
#include "mozilla/dom/HTMLPreElement.h"
|
||||
#include "mozilla/dom/HTMLPreElementBinding.h"
|
||||
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Pre)
|
||||
|
||||
|
@ -36,15 +35,14 @@ bool HTMLPreElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLPreElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_white_space)) {
|
||||
// wrap: empty
|
||||
if (aAttributes->GetAttr(nsGkAtoms::wrap))
|
||||
aDecls.SetKeywordValue(eCSSProperty_white_space,
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// wrap: empty
|
||||
if (aBuilder.GetAttr(nsGkAtoms::wrap)) {
|
||||
aBuilder.SetKeywordValue(eCSSProperty_white_space,
|
||||
StyleWhiteSpace::PreWrap);
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -21,15 +21,14 @@ class HTMLPreElement final : public nsGenericHTMLElement {
|
|||
// nsISupports
|
||||
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLPreElement, nsGenericHTMLElement)
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
// WebIDL API
|
||||
int32_t Width() const { return GetIntAttr(nsGkAtoms::width, 0); }
|
||||
|
@ -40,12 +39,10 @@ class HTMLPreElement final : public nsGenericHTMLElement {
|
|||
protected:
|
||||
virtual ~HTMLPreElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*>) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "mozilla/dom/HTMLOptionElement.h"
|
||||
#include "mozilla/dom/HTMLSelectElementBinding.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsContentList.h"
|
||||
|
@ -30,7 +30,6 @@
|
|||
#include "nsListControlFrame.h"
|
||||
#include "nsISelectControlFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "mozilla/PresState.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsStyleConsts.h"
|
||||
|
@ -1167,11 +1166,10 @@ bool HTMLSelectElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLSelectElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
nsGenericHTMLFormControlElementWithState::MapImageAlignAttributeInto(
|
||||
aAttributes, aDecls);
|
||||
nsGenericHTMLFormControlElementWithState::MapCommonAttributesInto(aAttributes,
|
||||
aDecls);
|
||||
aBuilder);
|
||||
nsGenericHTMLFormControlElementWithState::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
nsChangeHint HTMLSelectElement::GetAttributeChangeHint(const nsAtom* aAttribute,
|
||||
|
|
|
@ -540,8 +540,7 @@ class HTMLSelectElement final : public nsGenericHTMLFormControlElementWithState,
|
|||
nsString mPreviewValue;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
#include "mozilla/dom/HTMLQuoteElementBinding.h"
|
||||
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsIURI.h"
|
||||
|
@ -34,7 +30,7 @@ void HTMLSharedElement::GetHref(nsAString& aValue) {
|
|||
MOZ_ASSERT(mNodeInfo->Equals(nsGkAtoms::base),
|
||||
"This should only get called for <base> elements");
|
||||
nsAutoString href;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
|
||||
GetAttr(nsGkAtoms::href, href);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
Document* doc = OwnerDoc();
|
||||
|
|
|
@ -9,12 +9,11 @@
|
|||
#include "mozilla/dom/HTMLOListElementBinding.h"
|
||||
#include "mozilla/dom/HTMLUListElementBinding.h"
|
||||
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(SharedList)
|
||||
|
||||
|
@ -67,28 +66,28 @@ bool HTMLSharedListElement::ParseAttribute(
|
|||
}
|
||||
|
||||
void HTMLSharedListElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_list_style_type)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::type);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_list_style_type)) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::type);
|
||||
if (value && value->Type() == nsAttrValue::eEnum) {
|
||||
aDecls.SetKeywordValue(eCSSProperty_list_style_type,
|
||||
value->GetEnumValue());
|
||||
aBuilder.SetKeywordValue(eCSSProperty_list_style_type,
|
||||
value->GetEnumValue());
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
void HTMLSharedListElement::MapOLAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_counter_reset)) {
|
||||
const nsAttrValue* startAttr = aAttributes->GetAttr(nsGkAtoms::start);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_counter_reset)) {
|
||||
const nsAttrValue* startAttr = aBuilder.GetAttr(nsGkAtoms::start);
|
||||
bool haveStart = startAttr && startAttr->Type() == nsAttrValue::eInteger;
|
||||
int32_t start = 0;
|
||||
if (haveStart) {
|
||||
start = startAttr->GetIntegerValue() - 1;
|
||||
}
|
||||
bool haveReversed = !!aAttributes->GetAttr(nsGkAtoms::reversed);
|
||||
bool haveReversed = !!aBuilder.GetAttr(nsGkAtoms::reversed);
|
||||
if (haveReversed) {
|
||||
if (haveStart) {
|
||||
start += 2; // i.e. the attr value + 1
|
||||
|
@ -97,11 +96,11 @@ void HTMLSharedListElement::MapOLAttributesIntoRule(
|
|||
}
|
||||
}
|
||||
if (haveStart || haveReversed) {
|
||||
aDecls.SetCounterResetListItem(start, haveReversed);
|
||||
aBuilder.SetCounterResetListItem(start, haveReversed);
|
||||
}
|
||||
}
|
||||
|
||||
HTMLSharedListElement::MapAttributesIntoRule(aAttributes, aDecls);
|
||||
HTMLSharedListElement::MapAttributesIntoRule(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -22,14 +22,13 @@ class HTMLSharedListElement final : public nsGenericHTMLElement {
|
|||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
bool Reversed() const { return GetBoolAttr(nsGkAtoms::reversed); }
|
||||
void SetReversed(bool aReversed, mozilla::ErrorResult& rv) {
|
||||
|
@ -55,10 +54,8 @@ class HTMLSharedListElement final : public nsGenericHTMLElement {
|
|||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapOLAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
static void MapOLAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
|
||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
#include "mozilla/AttributeStyles.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Source)
|
||||
|
||||
|
@ -178,6 +178,12 @@ JSObject* HTMLSourceElement::WrapNode(JSContext* aCx,
|
|||
return HTMLSourceElement_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to map the image source attributes.
|
||||
* Note: This will override the declaration created by the presentation
|
||||
* attributes of HTMLImageElement (i.e. mapped by MapImageSizeAttributeInto).
|
||||
* https://html.spec.whatwg.org/multipage/embedded-content.html#the-source-element
|
||||
*/
|
||||
void HTMLSourceElement::BuildMappedAttributesForImage() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
|
@ -191,10 +197,6 @@ void HTMLSourceElement::BuildMappedAttributesForImage() {
|
|||
if (!document) {
|
||||
return;
|
||||
}
|
||||
AttributeStyles* attrStyles = document->GetAttributeStyles();
|
||||
if (!attrStyles) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nsAttrValue* width = mAttrs.GetAttr(nsGkAtoms::width);
|
||||
const nsAttrValue* height = mAttrs.GetAttr(nsGkAtoms::height);
|
||||
|
@ -202,36 +204,33 @@ void HTMLSourceElement::BuildMappedAttributesForImage() {
|
|||
return;
|
||||
}
|
||||
|
||||
const size_t count = (width ? 1 : 0) + (height ? 1 : 0);
|
||||
RefPtr<nsMappedAttributes> modifiableMapped(new (count) nsMappedAttributes(
|
||||
attrStyles, nsGenericHTMLElement::MapPictureSourceSizeAttributesInto));
|
||||
MOZ_ASSERT(modifiableMapped);
|
||||
|
||||
auto maybeSetAttr = [&](nsAtom* aName, const nsAttrValue* aValue) {
|
||||
if (!aValue) {
|
||||
return;
|
||||
}
|
||||
nsAttrValue val(*aValue);
|
||||
bool oldValueSet = false;
|
||||
modifiableMapped->SetAndSwapAttr(aName, val, &oldValueSet);
|
||||
};
|
||||
maybeSetAttr(nsGkAtoms::width, width);
|
||||
maybeSetAttr(nsGkAtoms::height, height);
|
||||
|
||||
RefPtr<nsMappedAttributes> newAttrs =
|
||||
attrStyles->UniqueMappedAttributes(modifiableMapped);
|
||||
NS_ENSURE_TRUE_VOID(newAttrs);
|
||||
|
||||
if (newAttrs != modifiableMapped) {
|
||||
// Reset the stylesheet of modifiableMapped so that it doesn't spend time
|
||||
// trying to remove itself from the hash. There is no risk that
|
||||
// modifiableMapped is in the hash since we created it ourselves and it
|
||||
// didn't come from the stylesheet (in which case it would not have been
|
||||
// modifiable).
|
||||
modifiableMapped->DropAttributeStylesReference();
|
||||
MappedDeclarationsBuilder builder(*this, *document);
|
||||
// We should set the missing property values with auto value to make sure it
|
||||
// overrides the declaration created by the presentation attributes of
|
||||
// HTMLImageElement. This can make sure we compute the ratio-dependent axis
|
||||
// size properly by the natural aspect-ratio of the image.
|
||||
//
|
||||
// Note: The spec doesn't specify this, so we follow the implementation in
|
||||
// other browsers.
|
||||
// Spec issue: https://github.com/whatwg/html/issues/8178.
|
||||
if (width) {
|
||||
MapDimensionAttributeInto(builder, eCSSProperty_width, *width);
|
||||
} else {
|
||||
builder.SetAutoValue(eCSSProperty_width);
|
||||
}
|
||||
|
||||
mMappedAttributesForImage = std::move(newAttrs);
|
||||
if (height) {
|
||||
MapDimensionAttributeInto(builder, eCSSProperty_height, *height);
|
||||
} else {
|
||||
builder.SetAutoValue(eCSSProperty_height);
|
||||
}
|
||||
|
||||
if (width && height) {
|
||||
DoMapAspectRatio(*width, *height, builder);
|
||||
} else {
|
||||
builder.SetAutoValue(eCSSProperty_aspect_ratio);
|
||||
}
|
||||
mMappedAttributesForImage = builder.TakeDeclarationBlock();
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -103,7 +103,7 @@ class HTMLSourceElement final : public nsGenericHTMLElement {
|
|||
SetUnsignedIntAttr(nsGkAtoms::height, aHeight, 0, aRv);
|
||||
}
|
||||
|
||||
const nsMappedAttributes* GetAttributesMappedForImage() const {
|
||||
const StyleLockedDeclarationBlock* GetAttributesMappedForImage() const {
|
||||
return mMappedAttributesForImage;
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ class HTMLSourceElement final : public nsGenericHTMLElement {
|
|||
|
||||
// The mapped attributes to HTMLImageElement if we are associated with a
|
||||
// <picture> with a valid <img>.
|
||||
RefPtr<nsMappedAttributes> mMappedAttributesForImage;
|
||||
RefPtr<StyleLockedDeclarationBlock> mMappedAttributesForImage;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -7,11 +7,6 @@
|
|||
#include "mozilla/dom/HTMLSpanElement.h"
|
||||
#include "mozilla/dom/HTMLSpanElementBinding.h"
|
||||
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsAtom.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Span)
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
|
||||
#include "mozilla/dom/HTMLTableCaptionElement.h"
|
||||
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "mozilla/dom/HTMLTableCaptionElementBinding.h"
|
||||
|
||||
|
@ -42,14 +41,15 @@ bool HTMLTableCaptionElement::ParseAttribute(
|
|||
}
|
||||
|
||||
void HTMLTableCaptionElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_caption_side)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
|
||||
if (value && value->Type() == nsAttrValue::eEnum)
|
||||
aDecls.SetKeywordValue(eCSSProperty_caption_side, value->GetEnumValue());
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_caption_side)) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::align);
|
||||
if (value && value->Type() == nsAttrValue::eEnum) {
|
||||
aBuilder.SetKeywordValue(eCSSProperty_caption_side,
|
||||
value->GetEnumValue());
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -24,25 +24,22 @@ class HTMLTableCaptionElement final : public nsGenericHTMLElement {
|
|||
SetHTMLAttr(nsGkAtoms::align, aAlign, aError);
|
||||
}
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
protected:
|
||||
virtual ~HTMLTableCaptionElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/HTMLTableElement.h"
|
||||
#include "mozilla/dom/HTMLTableRowElement.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "celldata.h"
|
||||
#include "mozilla/dom/HTMLTableCellElementBinding.h"
|
||||
|
@ -84,12 +83,11 @@ int32_t HTMLTableCellElement::CellIndex() const {
|
|||
return -1;
|
||||
}
|
||||
|
||||
nsMappedAttributes*
|
||||
StyleLockedDeclarationBlock*
|
||||
HTMLTableCellElement::GetMappedAttributesInheritedFromTable() const {
|
||||
if (HTMLTableElement* table = GetTable()) {
|
||||
return table->GetAttributesMappedForCell();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -162,27 +160,27 @@ bool HTMLTableCellElement::ParseAttribute(int32_t aNamespaceID,
|
|||
}
|
||||
|
||||
void HTMLTableCellElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MapImageSizeAttributesInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
MapImageSizeAttributesInto(aBuilder);
|
||||
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_white_space)) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_white_space)) {
|
||||
// nowrap: enum
|
||||
if (aAttributes->GetAttr(nsGkAtoms::nowrap)) {
|
||||
if (aBuilder.GetAttr(nsGkAtoms::nowrap)) {
|
||||
// See if our width is not a nonzero integer width.
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
|
||||
nsCompatibility mode = aDecls.Document()->GetCompatibilityMode();
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::width);
|
||||
nsCompatibility mode = aBuilder.Document().GetCompatibilityMode();
|
||||
if (!value || value->Type() != nsAttrValue::eInteger ||
|
||||
value->GetIntegerValue() == 0 || eCompatibility_NavQuirks != mode) {
|
||||
aDecls.SetKeywordValue(eCSSProperty_white_space,
|
||||
StyleWhiteSpace::Nowrap);
|
||||
aBuilder.SetKeywordValue(eCSSProperty_white_space,
|
||||
StyleWhiteSpace::Nowrap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapVAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapBackgroundAttributesInto(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -96,31 +96,28 @@ class HTMLTableCellElement final : public nsGenericHTMLElement {
|
|||
SetHTMLAttr(nsGkAtoms::bgcolor, aBgColor, aError);
|
||||
}
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
// Get mapped attributes of ancestor table, if any
|
||||
nsMappedAttributes* GetMappedAttributesInheritedFromTable() const;
|
||||
StyleLockedDeclarationBlock* GetMappedAttributesInheritedFromTable() const;
|
||||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
protected:
|
||||
virtual ~HTMLTableCellElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
HTMLTableElement* GetTable() const;
|
||||
|
||||
HTMLTableRowElement* GetRow() const;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
|
||||
#include "mozilla/dom/HTMLTableColElement.h"
|
||||
#include "mozilla/dom/HTMLTableColElementBinding.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(TableCol)
|
||||
|
||||
|
@ -58,25 +57,25 @@ bool HTMLTableColElement::ParseAttribute(int32_t aNamespaceID,
|
|||
}
|
||||
|
||||
void HTMLTableColElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty__x_span)) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty__x_span)) {
|
||||
// span: int
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::span);
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::span);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
int32_t val = value->GetIntegerValue();
|
||||
// Note: Do NOT use this code for table cells! The value "0"
|
||||
// means something special for colspan and rowspan, but for <col
|
||||
// span> and <colgroup span> it's just disallowed.
|
||||
if (val > 0) {
|
||||
aDecls.SetIntValue(eCSSProperty__x_span, value->GetIntegerValue());
|
||||
aBuilder.SetIntValue(eCSSProperty__x_span, value->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapWidthAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapWidthAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapVAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -47,24 +47,22 @@ class HTMLTableColElement final : public nsGenericHTMLElement {
|
|||
SetHTMLAttr(nsGkAtoms::width, aWidth, aError);
|
||||
}
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
protected:
|
||||
virtual ~HTMLTableColElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
#include "mozilla/dom/HTMLTableElement.h"
|
||||
#include "mozilla/AttributeStyles.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/DeclarationBlock.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/HTMLCollectionBinding.h"
|
||||
|
@ -499,8 +499,7 @@ void TableRowsCollection::NodeWillBeDestroyed(nsINode* aNode) {
|
|||
|
||||
HTMLTableElement::HTMLTableElement(
|
||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: nsGenericHTMLElement(std::move(aNodeInfo)),
|
||||
mTableInheritedAttributes(nullptr) {
|
||||
: nsGenericHTMLElement(std::move(aNodeInfo)) {
|
||||
SetHasWeirdParserInsertionMode();
|
||||
}
|
||||
|
||||
|
@ -840,7 +839,7 @@ bool HTMLTableElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLTableElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// XXX Bug 211636: This function is used by a single style rule
|
||||
// that's used to match two different type of elements -- tables, and
|
||||
// table cells. (nsHTMLTableCellElement overrides
|
||||
|
@ -852,56 +851,55 @@ void HTMLTableElement::MapAttributesIntoRule(
|
|||
// when the display type is changed).
|
||||
|
||||
// cellspacing
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellspacing);
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::cellspacing);
|
||||
if (value && value->Type() == nsAttrValue::eInteger &&
|
||||
!aDecls.PropertyIsSet(eCSSProperty_border_spacing)) {
|
||||
aDecls.SetPixelValue(eCSSProperty_border_spacing,
|
||||
float(value->GetIntegerValue()));
|
||||
!aBuilder.PropertyIsSet(eCSSProperty_border_spacing)) {
|
||||
aBuilder.SetPixelValue(eCSSProperty_border_spacing,
|
||||
float(value->GetIntegerValue()));
|
||||
}
|
||||
// align; Check for enumerated type (it may be another type if
|
||||
// illegal)
|
||||
value = aAttributes->GetAttr(nsGkAtoms::align);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::align);
|
||||
if (value && value->Type() == nsAttrValue::eEnum) {
|
||||
if (value->GetEnumValue() == uint8_t(StyleTextAlign::Center) ||
|
||||
value->GetEnumValue() == uint8_t(StyleTextAlign::MozCenter)) {
|
||||
aDecls.SetAutoValueIfUnset(eCSSProperty_margin_left);
|
||||
aDecls.SetAutoValueIfUnset(eCSSProperty_margin_right);
|
||||
aBuilder.SetAutoValueIfUnset(eCSSProperty_margin_left);
|
||||
aBuilder.SetAutoValueIfUnset(eCSSProperty_margin_right);
|
||||
}
|
||||
}
|
||||
|
||||
// bordercolor
|
||||
value = aAttributes->GetAttr(nsGkAtoms::bordercolor);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::bordercolor);
|
||||
nscolor color;
|
||||
if (value && value->GetColorValue(color)) {
|
||||
aDecls.SetColorValueIfUnset(eCSSProperty_border_top_color, color);
|
||||
aDecls.SetColorValueIfUnset(eCSSProperty_border_left_color, color);
|
||||
aDecls.SetColorValueIfUnset(eCSSProperty_border_bottom_color, color);
|
||||
aDecls.SetColorValueIfUnset(eCSSProperty_border_right_color, color);
|
||||
aBuilder.SetColorValueIfUnset(eCSSProperty_border_top_color, color);
|
||||
aBuilder.SetColorValueIfUnset(eCSSProperty_border_left_color, color);
|
||||
aBuilder.SetColorValueIfUnset(eCSSProperty_border_bottom_color, color);
|
||||
aBuilder.SetColorValueIfUnset(eCSSProperty_border_right_color, color);
|
||||
}
|
||||
|
||||
// border
|
||||
const nsAttrValue* borderValue = aAttributes->GetAttr(nsGkAtoms::border);
|
||||
if (borderValue) {
|
||||
if (const nsAttrValue* borderValue = aBuilder.GetAttr(nsGkAtoms::border)) {
|
||||
// border = 1 pixel default
|
||||
int32_t borderThickness = 1;
|
||||
|
||||
if (borderValue->Type() == nsAttrValue::eInteger)
|
||||
if (borderValue->Type() == nsAttrValue::eInteger) {
|
||||
borderThickness = borderValue->GetIntegerValue();
|
||||
}
|
||||
|
||||
// by default, set all border sides to the specified width
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_top_width,
|
||||
(float)borderThickness);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_left_width,
|
||||
(float)borderThickness);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_bottom_width,
|
||||
(float)borderThickness);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_right_width,
|
||||
(float)borderThickness);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_top_width,
|
||||
(float)borderThickness);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_left_width,
|
||||
(float)borderThickness);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_bottom_width,
|
||||
(float)borderThickness);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_right_width,
|
||||
(float)borderThickness);
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aBuilder);
|
||||
nsGenericHTMLElement::MapBackgroundAttributesInto(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
@ -929,66 +927,30 @@ nsMapRuleToAttributesFunc HTMLTableElement::GetAttributeMappingFunction()
|
|||
return &MapAttributesIntoRule;
|
||||
}
|
||||
|
||||
static void MapInheritedTableAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellpadding);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
// We have cellpadding. This will override our padding values if we
|
||||
// don't have any set.
|
||||
float pad = float(value->GetIntegerValue());
|
||||
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_padding_top, pad);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_padding_right, pad);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_padding_bottom, pad);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_padding_left, pad);
|
||||
}
|
||||
}
|
||||
|
||||
nsMappedAttributes* HTMLTableElement::GetAttributesMappedForCell() {
|
||||
return mTableInheritedAttributes;
|
||||
}
|
||||
|
||||
void HTMLTableElement::BuildInheritedAttributes() {
|
||||
NS_ASSERTION(!mTableInheritedAttributes,
|
||||
"potential leak, plus waste of work");
|
||||
MOZ_ASSERT(!mTableInheritedAttributes, "potential leak, plus waste of work");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
Document* document = GetComposedDoc();
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
AttributeStyles* attrStyles = document->GetAttributeStyles();
|
||||
if (!attrStyles) {
|
||||
const nsAttrValue* value = GetParsedAttr(nsGkAtoms::cellpadding);
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
RefPtr<nsMappedAttributes> newAttrs;
|
||||
if (const nsAttrValue* value = mAttrs.GetAttr(nsGkAtoms::cellpadding)) {
|
||||
RefPtr<nsMappedAttributes> modifiableMapped =
|
||||
new nsMappedAttributes(attrStyles, MapInheritedTableAttributesIntoRule);
|
||||
|
||||
if (modifiableMapped) {
|
||||
nsAttrValue val(*value);
|
||||
bool oldValueSet;
|
||||
modifiableMapped->SetAndSwapAttr(nsGkAtoms::cellpadding, val,
|
||||
&oldValueSet);
|
||||
}
|
||||
newAttrs = attrStyles->UniqueMappedAttributes(modifiableMapped);
|
||||
NS_ASSERTION(newAttrs, "out of memory, but handling gracefully");
|
||||
|
||||
if (newAttrs != modifiableMapped) {
|
||||
// Reset the stylesheet of modifiableMapped so that it doesn't spend time
|
||||
// trying to remove itself from the hash. There is no risk that
|
||||
// modifiableMapped is in the hash since we created it ourselves and it
|
||||
// didn't come from the attrStyles (in which case it would not have been
|
||||
// modifiable).
|
||||
modifiableMapped->DropAttributeStylesReference();
|
||||
}
|
||||
}
|
||||
mTableInheritedAttributes = newAttrs;
|
||||
NS_IF_ADDREF(mTableInheritedAttributes);
|
||||
// We have cellpadding. This will override our padding values if we don't
|
||||
// have any set.
|
||||
float pad = float(value->GetIntegerValue());
|
||||
MappedDeclarationsBuilder builder(*this, *document);
|
||||
builder.SetPixelValue(eCSSProperty_padding_top, pad);
|
||||
builder.SetPixelValue(eCSSProperty_padding_right, pad);
|
||||
builder.SetPixelValue(eCSSProperty_padding_bottom, pad);
|
||||
builder.SetPixelValue(eCSSProperty_padding_left, pad);
|
||||
mTableInheritedAttributes = builder.TakeDeclarationBlock();
|
||||
}
|
||||
|
||||
void HTMLTableElement::ReleaseInheritedAttributes() {
|
||||
NS_IF_RELEASE(mTableInheritedAttributes);
|
||||
mTableInheritedAttributes = nullptr;
|
||||
}
|
||||
|
||||
nsresult HTMLTableElement::BindToTree(BindContext& aContext, nsINode& aParent) {
|
||||
|
|
|
@ -171,7 +171,9 @@ class HTMLTableElement final : public nsGenericHTMLElement {
|
|||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTableElement,
|
||||
nsGenericHTMLElement)
|
||||
nsMappedAttributes* GetAttributesMappedForCell();
|
||||
StyleLockedDeclarationBlock* GetAttributesMappedForCell() const {
|
||||
return mTableInheritedAttributes;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~HTMLTableElement();
|
||||
|
@ -190,13 +192,12 @@ class HTMLTableElement final : public nsGenericHTMLElement {
|
|||
|
||||
RefPtr<nsContentList> mTBodies;
|
||||
RefPtr<TableRowsCollection> mRows;
|
||||
nsMappedAttributes* mTableInheritedAttributes;
|
||||
RefPtr<StyleLockedDeclarationBlock> mTableInheritedAttributes;
|
||||
void BuildInheritedAttributes();
|
||||
void ReleaseInheritedAttributes();
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
|
||||
#include "mozilla/dom/HTMLTableRowElement.h"
|
||||
#include "mozilla/dom/HTMLTableElement.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/HTMLTableRowElementBinding.h"
|
||||
|
@ -220,12 +219,12 @@ bool HTMLTableRowElement::ParseAttribute(int32_t aNamespaceID,
|
|||
}
|
||||
|
||||
void HTMLTableRowElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
nsGenericHTMLElement::MapHeightAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
nsGenericHTMLElement::MapHeightAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapVAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapBackgroundAttributesInto(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -84,8 +84,7 @@ class HTMLTableRowElement final : public nsGenericHTMLElement {
|
|||
RefPtr<nsContentList> mCells;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/HTMLTableSectionElement.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/HTMLTableSectionElementBinding.h"
|
||||
|
@ -141,18 +140,19 @@ bool HTMLTableSectionElement::ParseAttribute(
|
|||
}
|
||||
|
||||
void HTMLTableSectionElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// height: value
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_height)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
|
||||
if (value && value->Type() == nsAttrValue::eInteger)
|
||||
aDecls.SetPixelValue(eCSSProperty_height,
|
||||
(float)value->GetIntegerValue());
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_height)) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::height);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
aBuilder.SetPixelValue(eCSSProperty_height,
|
||||
(float)value->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
nsGenericHTMLElement::MapDivAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapVAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLElement::MapBackgroundAttributesInto(aBuilder);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -47,12 +47,11 @@ class HTMLTableSectionElement final : public nsGenericHTMLElement {
|
|||
SetHTMLAttr(nsGkAtoms::valign, aVAlign, aError);
|
||||
}
|
||||
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
|
||||
const override;
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
nsAttrValue& aResult) override;
|
||||
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
@ -68,8 +67,7 @@ class HTMLTableSectionElement final : public nsGenericHTMLElement {
|
|||
RefPtr<nsContentList> mRows;
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "mozilla/dom/HTMLTemplateElementBinding.h"
|
||||
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsAtom.h"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "mozilla/dom/HTMLTextAreaElementBinding.h"
|
||||
#include "mozilla/dom/MutationEventBinding.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/PresState.h"
|
||||
#include "mozilla/TextControlState.h"
|
||||
|
@ -32,8 +32,6 @@
|
|||
#include "nsITextControlFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsLinebreakConverter.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsStyleConsts.h"
|
||||
|
@ -378,20 +376,18 @@ bool HTMLTextAreaElement::ParseAttribute(int32_t aNamespaceID,
|
|||
}
|
||||
|
||||
void HTMLTextAreaElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// wrap=off
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_white_space)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::wrap);
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_white_space)) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::wrap);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
value->Equals(nsGkAtoms::OFF, eIgnoreCase)) {
|
||||
aDecls.SetKeywordValue(eCSSProperty_white_space, StyleWhiteSpace::Pre);
|
||||
aBuilder.SetKeywordValue(eCSSProperty_white_space, StyleWhiteSpace::Pre);
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLFormControlElementWithState::MapDivAlignAttributeInto(
|
||||
aAttributes, aDecls);
|
||||
nsGenericHTMLFormControlElementWithState::MapCommonAttributesInto(aAttributes,
|
||||
aDecls);
|
||||
nsGenericHTMLFormControlElementWithState::MapDivAlignAttributeInto(aBuilder);
|
||||
nsGenericHTMLFormControlElementWithState::MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
nsChangeHint HTMLTextAreaElement::GetAttributeChangeHint(
|
||||
|
|
|
@ -399,8 +399,7 @@ class HTMLTextAreaElement final : public TextControlElement,
|
|||
ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "nsIScriptError.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
|
|
@ -168,10 +168,9 @@ bool HTMLVideoElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
}
|
||||
|
||||
void HTMLVideoElement::MapAttributesIntoRule(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aDecls,
|
||||
MapAspectRatio::Yes);
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
MapImageSizeAttributesInto(aBuilder, MapAspectRatio::Yes);
|
||||
MapCommonAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
|
|
@ -191,8 +191,7 @@ class HTMLVideoElement final : public HTMLMediaElement {
|
|||
// SetVisualCloneTarget() instead.
|
||||
RefPtr<HTMLVideoElement> mVisualCloneSource;
|
||||
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations&);
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
|
||||
static bool IsVideoStatsEnabled();
|
||||
double TotalPlayTime() const;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "mozilla/HTMLEditor.h"
|
||||
#include "mozilla/IMEContentObserver.h"
|
||||
#include "mozilla/IMEStateManager.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
|
@ -28,7 +28,6 @@
|
|||
#include "nsQueryObject.h"
|
||||
#include "mozilla/dom/BindContext.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIFrameInlines.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
|
@ -1266,26 +1265,25 @@ bool nsGenericHTMLElement::ParseScrollingValue(const nsAString& aString,
|
|||
return aResult.ParseEnumValue(aString, kScrollingTable, false);
|
||||
}
|
||||
|
||||
static inline void MapLangAttributeInto(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations& aDecls) {
|
||||
const nsAttrValue* langValue = aAttributes->GetAttr(nsGkAtoms::lang);
|
||||
static inline void MapLangAttributeInto(MappedDeclarationsBuilder& aBuilder) {
|
||||
const nsAttrValue* langValue = aBuilder.GetAttr(nsGkAtoms::lang);
|
||||
if (!langValue) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(langValue->Type() == nsAttrValue::eAtom);
|
||||
aDecls.SetIdentAtomValueIfUnset(eCSSProperty__x_lang,
|
||||
langValue->GetAtomValue());
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_text_emphasis_position)) {
|
||||
aBuilder.SetIdentAtomValueIfUnset(eCSSProperty__x_lang,
|
||||
langValue->GetAtomValue());
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_text_emphasis_position)) {
|
||||
const nsAtom* lang = langValue->GetAtomValue();
|
||||
if (nsStyleUtil::MatchesLanguagePrefix(lang, u"zh")) {
|
||||
aDecls.SetKeywordValue(eCSSProperty_text_emphasis_position,
|
||||
StyleTextEmphasisPosition::UNDER.bits);
|
||||
aBuilder.SetKeywordValue(eCSSProperty_text_emphasis_position,
|
||||
StyleTextEmphasisPosition::UNDER.bits);
|
||||
} else if (nsStyleUtil::MatchesLanguagePrefix(lang, u"ja") ||
|
||||
nsStyleUtil::MatchesLanguagePrefix(lang, u"mn")) {
|
||||
// This branch is currently no part of the spec.
|
||||
// See bug 1040668 comment 69 and comment 75.
|
||||
aDecls.SetKeywordValue(eCSSProperty_text_emphasis_position,
|
||||
StyleTextEmphasisPosition::OVER.bits);
|
||||
aBuilder.SetKeywordValue(eCSSProperty_text_emphasis_position,
|
||||
StyleTextEmphasisPosition::OVER.bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1294,31 +1292,30 @@ static inline void MapLangAttributeInto(const nsMappedAttributes* aAttributes,
|
|||
* Handle attributes common to all html elements
|
||||
*/
|
||||
void nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty__moz_user_modify)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::contenteditable);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty__moz_user_modify)) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::contenteditable);
|
||||
if (value) {
|
||||
if (value->Equals(nsGkAtoms::_empty, eCaseMatters) ||
|
||||
value->Equals(nsGkAtoms::_true, eIgnoreCase)) {
|
||||
aDecls.SetKeywordValue(eCSSProperty__moz_user_modify,
|
||||
StyleUserModify::ReadWrite);
|
||||
aBuilder.SetKeywordValue(eCSSProperty__moz_user_modify,
|
||||
StyleUserModify::ReadWrite);
|
||||
} else if (value->Equals(nsGkAtoms::_false, eIgnoreCase)) {
|
||||
aDecls.SetKeywordValue(eCSSProperty__moz_user_modify,
|
||||
StyleUserModify::ReadOnly);
|
||||
aBuilder.SetKeywordValue(eCSSProperty__moz_user_modify,
|
||||
StyleUserModify::ReadOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MapLangAttributeInto(aAttributes, aDecls);
|
||||
MapLangAttributeInto(aBuilder);
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapCommonAttributesInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MapCommonAttributesIntoExceptHidden(aAttributes, aDecls);
|
||||
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_display)) {
|
||||
if (aAttributes->IndexOfAttr(nsGkAtoms::hidden) >= 0) {
|
||||
aDecls.SetKeywordValue(eCSSProperty_display, StyleDisplay::None);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
MapCommonAttributesIntoExceptHidden(aBuilder);
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_display)) {
|
||||
if (aBuilder.GetAttr(nsGkAtoms::hidden)) {
|
||||
aBuilder.SetKeywordValue(eCSSProperty_display, StyleDisplay::None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1364,24 +1361,24 @@ const Element::MappedAttributeEntry
|
|||
{nsGkAtoms::bgcolor}, {nullptr}};
|
||||
|
||||
void nsGenericHTMLElement::MapImageAlignAttributeInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::align);
|
||||
if (value && value->Type() == nsAttrValue::eEnum) {
|
||||
int32_t align = value->GetEnumValue();
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_float)) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_float)) {
|
||||
if (align == uint8_t(StyleTextAlign::Left)) {
|
||||
aDecls.SetKeywordValue(eCSSProperty_float, StyleFloat::Left);
|
||||
aBuilder.SetKeywordValue(eCSSProperty_float, StyleFloat::Left);
|
||||
} else if (align == uint8_t(StyleTextAlign::Right)) {
|
||||
aDecls.SetKeywordValue(eCSSProperty_float, StyleFloat::Right);
|
||||
aBuilder.SetKeywordValue(eCSSProperty_float, StyleFloat::Right);
|
||||
}
|
||||
}
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_vertical_align)) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_vertical_align)) {
|
||||
switch (align) {
|
||||
case uint8_t(StyleTextAlign::Left):
|
||||
case uint8_t(StyleTextAlign::Right):
|
||||
break;
|
||||
default:
|
||||
aDecls.SetKeywordValue(eCSSProperty_vertical_align, align);
|
||||
aBuilder.SetKeywordValue(eCSSProperty_vertical_align, align);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1389,78 +1386,74 @@ void nsGenericHTMLElement::MapImageAlignAttributeInto(
|
|||
}
|
||||
|
||||
void nsGenericHTMLElement::MapDivAlignAttributeInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_text_align)) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_text_align)) {
|
||||
// align: enum
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::align);
|
||||
if (value && value->Type() == nsAttrValue::eEnum)
|
||||
aDecls.SetKeywordValue(eCSSProperty_text_align, value->GetEnumValue());
|
||||
aBuilder.SetKeywordValue(eCSSProperty_text_align, value->GetEnumValue());
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapVAlignAttributeInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_vertical_align)) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_vertical_align)) {
|
||||
// align: enum
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::valign);
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::valign);
|
||||
if (value && value->Type() == nsAttrValue::eEnum)
|
||||
aDecls.SetKeywordValue(eCSSProperty_vertical_align,
|
||||
value->GetEnumValue());
|
||||
aBuilder.SetKeywordValue(eCSSProperty_vertical_align,
|
||||
value->GetEnumValue());
|
||||
}
|
||||
}
|
||||
|
||||
static void MapDimensionAttributeInto(MappedDeclarations& aDecls,
|
||||
nsCSSPropertyID aProp,
|
||||
const nsAttrValue& aValue) {
|
||||
MOZ_ASSERT(!aDecls.PropertyIsSet(aProp),
|
||||
void nsGenericHTMLElement::MapDimensionAttributeInto(
|
||||
MappedDeclarationsBuilder& aBuilder, nsCSSPropertyID aProp,
|
||||
const nsAttrValue& aValue) {
|
||||
MOZ_ASSERT(!aBuilder.PropertyIsSet(aProp),
|
||||
"Why mapping the same property twice?");
|
||||
if (aValue.Type() == nsAttrValue::eInteger) {
|
||||
return aDecls.SetPixelValue(aProp, aValue.GetIntegerValue());
|
||||
return aBuilder.SetPixelValue(aProp, aValue.GetIntegerValue());
|
||||
}
|
||||
if (aValue.Type() == nsAttrValue::ePercent) {
|
||||
return aDecls.SetPercentValue(aProp, aValue.GetPercentValue());
|
||||
return aBuilder.SetPercentValue(aProp, aValue.GetPercentValue());
|
||||
}
|
||||
if (aValue.Type() == nsAttrValue::eDoubleValue) {
|
||||
return aDecls.SetPixelValue(aProp, aValue.GetDoubleValue());
|
||||
return aBuilder.SetPixelValue(aProp, aValue.GetDoubleValue());
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapImageMarginAttributeInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
const nsAttrValue* value;
|
||||
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// hspace: value
|
||||
value = aAttributes->GetAttr(nsGkAtoms::hspace);
|
||||
if (value) {
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_margin_left, *value);
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_margin_right, *value);
|
||||
if (const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::hspace)) {
|
||||
MapDimensionAttributeInto(aBuilder, eCSSProperty_margin_left, *value);
|
||||
MapDimensionAttributeInto(aBuilder, eCSSProperty_margin_right, *value);
|
||||
}
|
||||
|
||||
// vspace: value
|
||||
value = aAttributes->GetAttr(nsGkAtoms::vspace);
|
||||
if (value) {
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_margin_top, *value);
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_margin_bottom, *value);
|
||||
if (const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::vspace)) {
|
||||
MapDimensionAttributeInto(aBuilder, eCSSProperty_margin_top, *value);
|
||||
MapDimensionAttributeInto(aBuilder, eCSSProperty_margin_bottom, *value);
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapWidthAttributeInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width)) {
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_width, *value);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
if (const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::width)) {
|
||||
MapDimensionAttributeInto(aBuilder, eCSSProperty_width, *value);
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapHeightAttributeInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height)) {
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_height, *value);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
if (const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::height)) {
|
||||
MapDimensionAttributeInto(aBuilder, eCSSProperty_height, *value);
|
||||
}
|
||||
}
|
||||
|
||||
static void DoMapAspectRatio(const nsAttrValue& aWidth,
|
||||
const nsAttrValue& aHeight,
|
||||
MappedDeclarations& aDecls) {
|
||||
void nsGenericHTMLElement::DoMapAspectRatio(
|
||||
const nsAttrValue& aWidth, const nsAttrValue& aHeight,
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
Maybe<double> w;
|
||||
if (aWidth.Type() == nsAttrValue::eInteger) {
|
||||
w.emplace(aWidth.GetIntegerValue());
|
||||
|
@ -1476,126 +1469,88 @@ static void DoMapAspectRatio(const nsAttrValue& aWidth,
|
|||
}
|
||||
|
||||
if (w && h) {
|
||||
aDecls.SetAspectRatio(*w, *h);
|
||||
aBuilder.SetAspectRatio(*w, *h);
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapImageSizeAttributesInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls,
|
||||
MapAspectRatio aMapAspectRatio) {
|
||||
auto* width = aAttributes->GetAttr(nsGkAtoms::width);
|
||||
auto* height = aAttributes->GetAttr(nsGkAtoms::height);
|
||||
MappedDeclarationsBuilder& aBuilder, MapAspectRatio aMapAspectRatio) {
|
||||
auto* width = aBuilder.GetAttr(nsGkAtoms::width);
|
||||
auto* height = aBuilder.GetAttr(nsGkAtoms::height);
|
||||
if (width) {
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_width, *width);
|
||||
MapDimensionAttributeInto(aBuilder, eCSSProperty_width, *width);
|
||||
}
|
||||
if (height) {
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_height, *height);
|
||||
MapDimensionAttributeInto(aBuilder, eCSSProperty_height, *height);
|
||||
}
|
||||
if (aMapAspectRatio == MapAspectRatio::Yes && width && height) {
|
||||
DoMapAspectRatio(*width, *height, aDecls);
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapPictureSourceSizeAttributesInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
const auto* width = aAttributes->GetAttr(nsGkAtoms::width);
|
||||
const auto* height = aAttributes->GetAttr(nsGkAtoms::height);
|
||||
if (!width && !height) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We should set the missing property values with auto value to make sure it
|
||||
// overrides the declaraion created by the presentation attributes of
|
||||
// HTMLImageElement. This can make sure we compute the ratio-dependent axis
|
||||
// size properly by the natural aspect-ratio of the image.
|
||||
//
|
||||
// Note: The spec doesn't specify this, so we follow the implementation in
|
||||
// other browsers.
|
||||
// Spec issue: https://github.com/whatwg/html/issues/8178.
|
||||
if (width) {
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_width, *width);
|
||||
} else {
|
||||
aDecls.SetAutoValue(eCSSProperty_width);
|
||||
}
|
||||
|
||||
if (height) {
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_height, *height);
|
||||
} else {
|
||||
aDecls.SetAutoValue(eCSSProperty_height);
|
||||
}
|
||||
|
||||
if (width && height) {
|
||||
DoMapAspectRatio(*width, *height, aDecls);
|
||||
} else {
|
||||
aDecls.SetAutoValue(eCSSProperty_aspect_ratio);
|
||||
DoMapAspectRatio(*width, *height, aBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapAspectRatioInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
auto* width = aAttributes->GetAttr(nsGkAtoms::width);
|
||||
auto* height = aAttributes->GetAttr(nsGkAtoms::height);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
auto* width = aBuilder.GetAttr(nsGkAtoms::width);
|
||||
auto* height = aBuilder.GetAttr(nsGkAtoms::height);
|
||||
if (width && height) {
|
||||
DoMapAspectRatio(*width, *height, aDecls);
|
||||
DoMapAspectRatio(*width, *height, aBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapImageBorderAttributeInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// border: pixels
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::border);
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::border);
|
||||
if (!value) return;
|
||||
|
||||
nscoord val = 0;
|
||||
if (value->Type() == nsAttrValue::eInteger) val = value->GetIntegerValue();
|
||||
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_top_width, (float)val);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_right_width, (float)val);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_bottom_width, (float)val);
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_border_left_width, (float)val);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_top_width, (float)val);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_right_width, (float)val);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_bottom_width, (float)val);
|
||||
aBuilder.SetPixelValueIfUnset(eCSSProperty_border_left_width, (float)val);
|
||||
|
||||
aDecls.SetKeywordValueIfUnset(eCSSProperty_border_top_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aDecls.SetKeywordValueIfUnset(eCSSProperty_border_right_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aDecls.SetKeywordValueIfUnset(eCSSProperty_border_bottom_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aDecls.SetKeywordValueIfUnset(eCSSProperty_border_left_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aBuilder.SetKeywordValueIfUnset(eCSSProperty_border_top_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aBuilder.SetKeywordValueIfUnset(eCSSProperty_border_right_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aBuilder.SetKeywordValueIfUnset(eCSSProperty_border_bottom_style,
|
||||
StyleBorderStyle::Solid);
|
||||
aBuilder.SetKeywordValueIfUnset(eCSSProperty_border_left_style,
|
||||
StyleBorderStyle::Solid);
|
||||
|
||||
aDecls.SetCurrentColorIfUnset(eCSSProperty_border_top_color);
|
||||
aDecls.SetCurrentColorIfUnset(eCSSProperty_border_right_color);
|
||||
aDecls.SetCurrentColorIfUnset(eCSSProperty_border_bottom_color);
|
||||
aDecls.SetCurrentColorIfUnset(eCSSProperty_border_left_color);
|
||||
aBuilder.SetCurrentColorIfUnset(eCSSProperty_border_top_color);
|
||||
aBuilder.SetCurrentColorIfUnset(eCSSProperty_border_right_color);
|
||||
aBuilder.SetCurrentColorIfUnset(eCSSProperty_border_bottom_color);
|
||||
aBuilder.SetCurrentColorIfUnset(eCSSProperty_border_left_color);
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapBackgroundInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_background_image)) {
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_background_image)) {
|
||||
// background
|
||||
nsAttrValue* value =
|
||||
const_cast<nsAttrValue*>(aAttributes->GetAttr(nsGkAtoms::background));
|
||||
if (value) {
|
||||
aDecls.SetBackgroundImage(*value);
|
||||
if (const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::background)) {
|
||||
aBuilder.SetBackgroundImage(*value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapBGColorInto(const nsMappedAttributes* aAttributes,
|
||||
MappedDeclarations& aDecls) {
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_background_color)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::bgcolor);
|
||||
nscolor color;
|
||||
if (value && value->GetColorValue(color)) {
|
||||
aDecls.SetColorValue(eCSSProperty_background_color, color);
|
||||
}
|
||||
void nsGenericHTMLElement::MapBGColorInto(MappedDeclarationsBuilder& aBuilder) {
|
||||
if (aBuilder.PropertyIsSet(eCSSProperty_background_color)) {
|
||||
return;
|
||||
}
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::bgcolor);
|
||||
nscolor color;
|
||||
if (value && value->GetColorValue(color)) {
|
||||
aBuilder.SetColorValue(eCSSProperty_background_color, color);
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLElement::MapBackgroundAttributesInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
MapBackgroundInto(aAttributes, aDecls);
|
||||
MapBGColorInto(aAttributes, aDecls);
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
MapBackgroundInto(aBuilder);
|
||||
MapBGColorInto(aBuilder);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "nsMappedAttributeElement.h"
|
||||
#include "nsNameSpaceManager.h" // for kNameSpaceID_None
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsStyledElement.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/DOMRect.h"
|
||||
|
@ -27,6 +27,8 @@ class nsILayoutHistoryState;
|
|||
class nsIURI;
|
||||
struct nsSize;
|
||||
|
||||
enum nsCSSPropertyID : int32_t;
|
||||
|
||||
namespace mozilla {
|
||||
class EditorBase;
|
||||
class ErrorResult;
|
||||
|
@ -41,7 +43,7 @@ class HTMLFormElement;
|
|||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
using nsGenericHTMLElementBase = nsMappedAttributeElement;
|
||||
using nsGenericHTMLElementBase = nsStyledElement;
|
||||
|
||||
/**
|
||||
* A common superclass for HTML elements
|
||||
|
@ -495,17 +497,13 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
|
|||
* @param aData the returned rule data [INOUT]
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapCommonAttributesInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapCommonAttributesInto(mozilla::MappedDeclarationsBuilder&);
|
||||
/**
|
||||
* Same as MapCommonAttributesInto except that it does not handle hidden.
|
||||
*
|
||||
* @param aAttributes the list of attributes to map
|
||||
* @param aData the returned rule data [INOUT]
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapCommonAttributesIntoExceptHidden(
|
||||
const nsMappedAttributes* aAttributes, mozilla::MappedDeclarations&);
|
||||
mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
static const MappedAttributeEntry sCommonAttributeMap[];
|
||||
static const MappedAttributeEntry sImageMarginSizeAttributeMap[];
|
||||
|
@ -516,46 +514,28 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
|
|||
static const MappedAttributeEntry sBackgroundColorAttributeMap[];
|
||||
|
||||
/**
|
||||
* Helper to map the align attribute into a style struct.
|
||||
*
|
||||
* @param aAttributes the list of attributes to map
|
||||
* @param aData the returned rule data [INOUT]
|
||||
* Helper to map the align attribute.
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapImageAlignAttributeInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapImageAlignAttributeInto(mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
/**
|
||||
* Helper to map the align attribute into a style struct for things
|
||||
* like <div>, <h1>, etc.
|
||||
*
|
||||
* @param aAttributes the list of attributes to map
|
||||
* @param aData the returned rule data [INOUT]
|
||||
* Helper to map the align attribute for things like <div>, <h1>, etc.
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapDivAlignAttributeInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapDivAlignAttributeInto(mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
/**
|
||||
* Helper to map the valign attribute into a style struct for things
|
||||
* like <col>, <tr>, <section>, etc.
|
||||
*
|
||||
* @param aAttributes the list of attributes to map
|
||||
* @param aData the returned rule data [INOUT]
|
||||
* Helper to map the valign attribute for things like <col>, <tr>, <section>.
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapVAlignAttributeInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapVAlignAttributeInto(mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
/**
|
||||
* Helper to map the image border attribute into a style struct.
|
||||
*
|
||||
* @param aAttributes the list of attributes to map
|
||||
* @param aData the returned rule data [INOUT]
|
||||
* Helper to map the image border attribute.
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapImageBorderAttributeInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapImageBorderAttributeInto(mozilla::MappedDeclarationsBuilder&);
|
||||
/**
|
||||
* Helper to map the image margin attribute into a style struct.
|
||||
*
|
||||
|
@ -563,8 +543,21 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
|
|||
* @param aData the returned rule data [INOUT]
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapImageMarginAttributeInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapImageMarginAttributeInto(mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
/**
|
||||
* Helper to map a given dimension (width/height) into the declaration
|
||||
* block, handling percentages and numbers.
|
||||
*/
|
||||
static void MapDimensionAttributeInto(mozilla::MappedDeclarationsBuilder&,
|
||||
nsCSSPropertyID, const nsAttrValue&);
|
||||
|
||||
/**
|
||||
* Maps the aspect ratio given width and height attributes.
|
||||
*/
|
||||
static void DoMapAspectRatio(const nsAttrValue& aWidth,
|
||||
const nsAttrValue& aHeight,
|
||||
mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
// Whether to map the width and height attributes to aspect-ratio.
|
||||
enum class MapAspectRatio { No, Yes };
|
||||
|
@ -572,18 +565,8 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
|
|||
/**
|
||||
* Helper to map the image position attribute into a style struct.
|
||||
*/
|
||||
static void MapImageSizeAttributesInto(const nsMappedAttributes*,
|
||||
mozilla::MappedDeclarations&,
|
||||
static void MapImageSizeAttributesInto(mozilla::MappedDeclarationsBuilder&,
|
||||
MapAspectRatio = MapAspectRatio::No);
|
||||
/**
|
||||
* Helper to map the iamge source attributes into a style stuct.
|
||||
* Note:
|
||||
* This will override the declaration created by the presentation attributes
|
||||
* of HTMLImageElement (i.e. mapped by MapImageSizeAttributeInto).
|
||||
* https://html.spec.whatwg.org/multipage/embedded-content.html#the-source-element
|
||||
*/
|
||||
static void MapPictureSourceSizeAttributesInto(const nsMappedAttributes*,
|
||||
mozilla::MappedDeclarations&);
|
||||
|
||||
/**
|
||||
* Helper to map the width and height attributes into the aspect-ratio
|
||||
|
@ -594,8 +577,7 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
|
|||
* MapImageSizeAttributesInto instead, passing MapAspectRatio::Yes instead, as
|
||||
* that'd be faster.
|
||||
*/
|
||||
static void MapAspectRatioInto(const nsMappedAttributes*,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapAspectRatioInto(mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
/**
|
||||
* Helper to map `width` attribute into a style struct.
|
||||
|
@ -604,57 +586,33 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
|
|||
* @param aData the returned rule data [INOUT]
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapWidthAttributeInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapWidthAttributeInto(mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
/**
|
||||
* Helper to map `height` attribute into a style struct.
|
||||
*
|
||||
* @param aAttributes the list of attributes to map
|
||||
* @param aData the returned rule data [INOUT]
|
||||
* Helper to map `height` attribute.
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapHeightAttributeInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapHeightAttributeInto(mozilla::MappedDeclarationsBuilder&);
|
||||
/**
|
||||
* Helper to map the background attribute
|
||||
* into a style struct.
|
||||
*
|
||||
* @param aAttributes the list of attributes to map
|
||||
* @param aData the returned rule data [INOUT]
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapBackgroundInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapBackgroundInto(mozilla::MappedDeclarationsBuilder&);
|
||||
/**
|
||||
* Helper to map the bgcolor attribute
|
||||
* into a style struct.
|
||||
*
|
||||
* @param aAttributes the list of attributes to map
|
||||
* @param aData the returned rule data [INOUT]
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapBGColorInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapBGColorInto(mozilla::MappedDeclarationsBuilder&);
|
||||
/**
|
||||
* Helper to map the background attributes (currently background and bgcolor)
|
||||
* into a style struct.
|
||||
*
|
||||
* @param aAttributes the list of attributes to map
|
||||
* @param aData the returned rule data [INOUT]
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapBackgroundAttributesInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapBackgroundAttributesInto(mozilla::MappedDeclarationsBuilder&);
|
||||
/**
|
||||
* Helper to map the scrolling attribute on FRAME and IFRAME
|
||||
* into a style struct.
|
||||
*
|
||||
* @param aAttributes the list of attributes to map
|
||||
* @param aData the returned rule data [INOUT]
|
||||
* Helper to map the scrolling attribute on FRAME and IFRAME.
|
||||
* @see GetAttributeMappingFunction
|
||||
*/
|
||||
static void MapScrollingAttributeInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapScrollingAttributeInto(mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
// Form Helper Routines
|
||||
/**
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "nsIContentInlines.h"
|
||||
#include "nsITableCellLayout.h" // for MAX_COLSPAN / MAX_ROWSPAN
|
||||
#include "nsCSSValue.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsPresContext.h"
|
||||
|
@ -27,7 +26,7 @@
|
|||
#include "nsIURI.h"
|
||||
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/MappedDeclarations.h"
|
||||
#include "mozilla/MappedDeclarationsBuilder.h"
|
||||
#include "mozilla/dom/MathMLElementBinding.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -47,10 +46,10 @@ static nsresult ReportLengthParseError(const nsString& aValue,
|
|||
}
|
||||
|
||||
static nsresult ReportParseErrorNoTag(const nsString& aValue, nsAtom* aAtom,
|
||||
Document* aDocument) {
|
||||
Document& aDocument) {
|
||||
AutoTArray<nsString, 2> argv = {aValue, nsDependentAtomString(aAtom)};
|
||||
return nsContentUtils::ReportToConsole(
|
||||
nsIScriptError::errorFlag, "MathML"_ns, aDocument,
|
||||
nsIScriptError::errorFlag, "MathML"_ns, &aDocument,
|
||||
nsContentUtils::eMATHML_PROPERTIES, "AttributeParsingErrorNoTag", argv);
|
||||
}
|
||||
|
||||
|
@ -147,10 +146,10 @@ bool MathMLElement::IsAttributeMapped(const nsAtom* aAttribute) const {
|
|||
}
|
||||
|
||||
nsMapRuleToAttributesFunc MathMLElement::GetAttributeMappingFunction() const {
|
||||
// It doesn't really matter what our tag is here, because only attributes
|
||||
// that satisfy IsAttributeMapped will be stored in the mapped attributes
|
||||
// list and available to the mapping function
|
||||
return &MapMathMLAttributesInto;
|
||||
if (mNodeInfo->Equals(nsGkAtoms::mtable_)) {
|
||||
return &MapMTableAttributesInto;
|
||||
}
|
||||
return &MapGlobalMathMLAttributesInto;
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -356,8 +355,39 @@ bool MathMLElement::ParseNumericValue(const nsString& aString,
|
|||
return true;
|
||||
}
|
||||
|
||||
void MathMLElement::MapMathMLAttributesInto(
|
||||
const nsMappedAttributes* aAttributes, MappedDeclarations& aDecls) {
|
||||
void MathMLElement::MapMTableAttributesInto(
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// width
|
||||
//
|
||||
// "Specifies the desired width of the entire table and is intended for
|
||||
// visual user agents. When the value is a percentage value, the value is
|
||||
// relative to the horizontal space a MathML renderer has available for the
|
||||
// math element. When the value is "auto", the MathML renderer should
|
||||
// calculate the table width from its contents using whatever layout
|
||||
// algorithm it chooses. "
|
||||
//
|
||||
// values: "auto" | length
|
||||
// default: auto
|
||||
//
|
||||
if (!aBuilder.PropertyIsSet(eCSSProperty_width)) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::width);
|
||||
nsCSSValue width;
|
||||
// This does not handle auto and unitless values
|
||||
if (value && value->Type() == nsAttrValue::eString) {
|
||||
ParseNumericValue(value->GetStringValue(), width, 0,
|
||||
&aBuilder.Document());
|
||||
if (width.GetUnit() == eCSSUnit_Percent) {
|
||||
aBuilder.SetPercentValue(eCSSProperty_width, width.GetPercentValue());
|
||||
} else if (width.GetUnit() != eCSSUnit_Null) {
|
||||
aBuilder.SetLengthValue(eCSSProperty_width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
MapGlobalMathMLAttributesInto(aBuilder);
|
||||
}
|
||||
|
||||
void MathMLElement::MapGlobalMathMLAttributesInto(
|
||||
MappedDeclarationsBuilder& aBuilder) {
|
||||
// scriptsizemultiplier
|
||||
//
|
||||
// "Specifies the multiplier to be used to adjust font size due to changes
|
||||
|
@ -366,26 +396,28 @@ void MathMLElement::MapMathMLAttributesInto(
|
|||
// values: number
|
||||
// default: 0.71
|
||||
//
|
||||
const nsAttrValue* value =
|
||||
aAttributes->GetAttr(nsGkAtoms::scriptsizemultiplier_);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
!aDecls.PropertyIsSet(eCSSProperty__moz_script_size_multiplier)) {
|
||||
aDecls.Document()->WarnOnceAbout(
|
||||
dom::DeprecatedOperations::
|
||||
eMathML_DeprecatedScriptsizemultiplierAttribute);
|
||||
auto str = value->GetStringValue();
|
||||
str.CompressWhitespace();
|
||||
// MathML numbers can't have leading '+'
|
||||
if (str.Length() > 0 && str.CharAt(0) != '+') {
|
||||
nsresult errorCode;
|
||||
float floatValue = str.ToFloat(&errorCode);
|
||||
// Negative scriptsizemultipliers are not parsed
|
||||
if (NS_SUCCEEDED(errorCode) && floatValue >= 0.0f) {
|
||||
aDecls.SetNumberValue(eCSSProperty__moz_script_size_multiplier,
|
||||
floatValue);
|
||||
} else {
|
||||
ReportParseErrorNoTag(str, nsGkAtoms::scriptsizemultiplier_,
|
||||
aDecls.Document());
|
||||
if (!StaticPrefs::mathml_scriptsizemultiplier_attribute_disabled()) {
|
||||
const nsAttrValue* value =
|
||||
aBuilder.GetAttr(nsGkAtoms::scriptsizemultiplier_);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
!aBuilder.PropertyIsSet(eCSSProperty__moz_script_size_multiplier)) {
|
||||
aBuilder.Document().WarnOnceAbout(
|
||||
dom::DeprecatedOperations::
|
||||
eMathML_DeprecatedScriptsizemultiplierAttribute);
|
||||
auto str = value->GetStringValue();
|
||||
str.CompressWhitespace();
|
||||
// MathML numbers can't have leading '+'
|
||||
if (str.Length() > 0 && str.CharAt(0) != '+') {
|
||||
nsresult errorCode;
|
||||
float floatValue = str.ToFloat(&errorCode);
|
||||
// Negative scriptsizemultipliers are not parsed
|
||||
if (NS_SUCCEEDED(errorCode) && floatValue >= 0.0f) {
|
||||
aBuilder.SetNumberValue(eCSSProperty__moz_script_size_multiplier,
|
||||
floatValue);
|
||||
} else {
|
||||
ReportParseErrorNoTag(str, nsGkAtoms::scriptsizemultiplier_,
|
||||
aBuilder.Document());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -401,21 +433,24 @@ void MathMLElement::MapMathMLAttributesInto(
|
|||
// We don't allow negative values.
|
||||
// Unitless and percent values give a multiple of the default value.
|
||||
//
|
||||
value = aAttributes->GetAttr(nsGkAtoms::scriptminsize_);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
!aDecls.PropertyIsSet(eCSSProperty__moz_script_min_size)) {
|
||||
aDecls.Document()->WarnOnceAbout(
|
||||
dom::DeprecatedOperations::eMathML_DeprecatedScriptminsizeAttribute);
|
||||
nsCSSValue scriptMinSize;
|
||||
ParseNumericValue(value->GetStringValue(), scriptMinSize, 0,
|
||||
aDecls.Document());
|
||||
if (!StaticPrefs::mathml_scriptminsize_attribute_disabled()) {
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::scriptminsize_);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
!aBuilder.PropertyIsSet(eCSSProperty__moz_script_min_size)) {
|
||||
aBuilder.Document().WarnOnceAbout(
|
||||
dom::DeprecatedOperations::eMathML_DeprecatedScriptminsizeAttribute);
|
||||
nsCSSValue scriptMinSize;
|
||||
ParseNumericValue(value->GetStringValue(), scriptMinSize, 0,
|
||||
&aBuilder.Document());
|
||||
|
||||
if (scriptMinSize.GetUnit() == eCSSUnit_Percent) {
|
||||
scriptMinSize.SetFloatValue(8.0 * scriptMinSize.GetPercentValue(),
|
||||
eCSSUnit_Point);
|
||||
}
|
||||
if (scriptMinSize.GetUnit() != eCSSUnit_Null) {
|
||||
aDecls.SetLengthValue(eCSSProperty__moz_script_min_size, scriptMinSize);
|
||||
if (scriptMinSize.GetUnit() == eCSSUnit_Percent) {
|
||||
scriptMinSize.SetFloatValue(8.0f * scriptMinSize.GetPercentValue(),
|
||||
eCSSUnit_Point);
|
||||
}
|
||||
if (scriptMinSize.GetUnit() != eCSSUnit_Null) {
|
||||
aBuilder.SetLengthValue(eCSSProperty__moz_script_min_size,
|
||||
scriptMinSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,9 +465,9 @@ void MathMLElement::MapMathMLAttributesInto(
|
|||
// values: ( "+" | "-" )? unsigned-integer
|
||||
// default: inherited
|
||||
//
|
||||
value = aAttributes->GetAttr(nsGkAtoms::scriptlevel_);
|
||||
const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::scriptlevel_);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
!aDecls.PropertyIsSet(eCSSProperty_math_depth)) {
|
||||
!aBuilder.PropertyIsSet(eCSSProperty_math_depth)) {
|
||||
auto str = value->GetStringValue();
|
||||
str.CompressWhitespace();
|
||||
if (str.Length() > 0) {
|
||||
|
@ -441,26 +476,27 @@ void MathMLElement::MapMathMLAttributesInto(
|
|||
if (NS_SUCCEEDED(errorCode)) {
|
||||
char16_t ch = str.CharAt(0);
|
||||
bool isRelativeScriptLevel = (ch == '+' || ch == '-');
|
||||
aDecls.SetMathDepthValue(intValue, isRelativeScriptLevel);
|
||||
aBuilder.SetMathDepthValue(intValue, isRelativeScriptLevel);
|
||||
} else {
|
||||
ReportParseErrorNoTag(str, nsGkAtoms::scriptlevel_, aDecls.Document());
|
||||
ReportParseErrorNoTag(str, nsGkAtoms::scriptlevel_,
|
||||
aBuilder.Document());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mathsize
|
||||
// https://w3c.github.io/mathml-core/#dfn-mathsize
|
||||
value = aAttributes->GetAttr(nsGkAtoms::mathsize_);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::mathsize_);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
!aDecls.PropertyIsSet(eCSSProperty_font_size)) {
|
||||
!aBuilder.PropertyIsSet(eCSSProperty_font_size)) {
|
||||
auto str = value->GetStringValue();
|
||||
nsCSSValue fontSize;
|
||||
ParseNumericValue(str, fontSize, 0, nullptr);
|
||||
if (fontSize.GetUnit() == eCSSUnit_Percent) {
|
||||
aDecls.SetPercentValue(eCSSProperty_font_size,
|
||||
fontSize.GetPercentValue());
|
||||
aBuilder.SetPercentValue(eCSSProperty_font_size,
|
||||
fontSize.GetPercentValue());
|
||||
} else if (fontSize.GetUnit() != eCSSUnit_Null) {
|
||||
aDecls.SetLengthValue(eCSSProperty_font_size, fontSize);
|
||||
aBuilder.SetLengthValue(eCSSProperty_font_size, fontSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -475,9 +511,9 @@ void MathMLElement::MapMathMLAttributesInto(
|
|||
// "monospace" | "initial" | "tailed" | "looped" | "stretched"
|
||||
// default: normal (except on <mi>)
|
||||
//
|
||||
value = aAttributes->GetAttr(nsGkAtoms::mathvariant_);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::mathvariant_);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
!aDecls.PropertyIsSet(eCSSProperty__moz_math_variant)) {
|
||||
!aBuilder.PropertyIsSet(eCSSProperty__moz_math_variant)) {
|
||||
auto str = value->GetStringValue();
|
||||
str.CompressWhitespace();
|
||||
static const char sizes[19][23] = {"normal",
|
||||
|
@ -519,7 +555,7 @@ void MathMLElement::MapMathMLAttributesInto(
|
|||
StyleMathVariant::Stretched};
|
||||
for (uint32_t i = 0; i < ArrayLength(sizes); ++i) {
|
||||
if (str.LowerCaseEqualsASCII(sizes[i])) {
|
||||
aDecls.SetKeywordValue(eCSSProperty__moz_math_variant, values[i]);
|
||||
aBuilder.SetKeywordValue(eCSSProperty__moz_math_variant, values[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -527,60 +563,34 @@ void MathMLElement::MapMathMLAttributesInto(
|
|||
|
||||
// mathbackground
|
||||
// https://w3c.github.io/mathml-core/#dfn-mathbackground
|
||||
value = aAttributes->GetAttr(nsGkAtoms::mathbackground_);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::mathbackground_);
|
||||
if (value) {
|
||||
nscolor color;
|
||||
if (value->GetColorValue(color)) {
|
||||
aDecls.SetColorValueIfUnset(eCSSProperty_background_color, color);
|
||||
aBuilder.SetColorValueIfUnset(eCSSProperty_background_color, color);
|
||||
}
|
||||
}
|
||||
|
||||
// mathcolor
|
||||
// https://w3c.github.io/mathml-core/#dfn-mathcolor
|
||||
value = aAttributes->GetAttr(nsGkAtoms::mathcolor_);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::mathcolor_);
|
||||
nscolor color;
|
||||
if (value && value->GetColorValue(color)) {
|
||||
aDecls.SetColorValueIfUnset(eCSSProperty_color, color);
|
||||
}
|
||||
|
||||
// width
|
||||
//
|
||||
// "Specifies the desired width of the entire table and is intended for
|
||||
// visual user agents. When the value is a percentage value, the value is
|
||||
// relative to the horizontal space a MathML renderer has available for the
|
||||
// math element. When the value is "auto", the MathML renderer should
|
||||
// calculate the table width from its contents using whatever layout
|
||||
// algorithm it chooses. "
|
||||
//
|
||||
// values: "auto" | length
|
||||
// default: auto
|
||||
//
|
||||
if (!aDecls.PropertyIsSet(eCSSProperty_width)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
|
||||
nsCSSValue width;
|
||||
// This does not handle auto and unitless values
|
||||
if (value && value->Type() == nsAttrValue::eString) {
|
||||
ParseNumericValue(value->GetStringValue(), width, 0, aDecls.Document());
|
||||
if (width.GetUnit() == eCSSUnit_Percent) {
|
||||
aDecls.SetPercentValue(eCSSProperty_width, width.GetPercentValue());
|
||||
} else if (width.GetUnit() != eCSSUnit_Null) {
|
||||
aDecls.SetLengthValue(eCSSProperty_width, width);
|
||||
}
|
||||
}
|
||||
aBuilder.SetColorValueIfUnset(eCSSProperty_color, color);
|
||||
}
|
||||
|
||||
// dir
|
||||
// https://w3c.github.io/mathml-core/#dfn-dir
|
||||
value = aAttributes->GetAttr(nsGkAtoms::dir);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::dir);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
!aDecls.PropertyIsSet(eCSSProperty_direction)) {
|
||||
!aBuilder.PropertyIsSet(eCSSProperty_direction)) {
|
||||
auto str = value->GetStringValue();
|
||||
static const char dirs[][4] = {"ltr", "rtl"};
|
||||
static const StyleDirection dirValues[MOZ_ARRAY_LENGTH(dirs)] = {
|
||||
StyleDirection::Ltr, StyleDirection::Rtl};
|
||||
for (uint32_t i = 0; i < ArrayLength(dirs); ++i) {
|
||||
if (str.LowerCaseEqualsASCII(dirs[i])) {
|
||||
aDecls.SetKeywordValue(eCSSProperty_direction, dirValues[i]);
|
||||
aBuilder.SetKeywordValue(eCSSProperty_direction, dirValues[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -588,16 +598,16 @@ void MathMLElement::MapMathMLAttributesInto(
|
|||
|
||||
// displaystyle
|
||||
// https://mathml-refresh.github.io/mathml-core/#dfn-displaystyle
|
||||
value = aAttributes->GetAttr(nsGkAtoms::displaystyle_);
|
||||
value = aBuilder.GetAttr(nsGkAtoms::displaystyle_);
|
||||
if (value && value->Type() == nsAttrValue::eString &&
|
||||
!aDecls.PropertyIsSet(eCSSProperty_math_style)) {
|
||||
!aBuilder.PropertyIsSet(eCSSProperty_math_style)) {
|
||||
auto str = value->GetStringValue();
|
||||
static const char displaystyles[][6] = {"false", "true"};
|
||||
static const StyleMathStyle mathStyle[MOZ_ARRAY_LENGTH(displaystyles)] = {
|
||||
StyleMathStyle::Compact, StyleMathStyle::Normal};
|
||||
for (uint32_t i = 0; i < ArrayLength(displaystyles); ++i) {
|
||||
if (str.LowerCaseEqualsASCII(displaystyles[i])) {
|
||||
aDecls.SetKeywordValue(eCSSProperty_math_style, mathStyle[i]);
|
||||
aBuilder.SetKeywordValue(eCSSProperty_math_style, mathStyle[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#define mozilla_dom_MathMLElement_h_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsMappedAttributeElement.h"
|
||||
#include "nsStyledElement.h"
|
||||
#include "Link.h"
|
||||
|
||||
class nsCSSValue;
|
||||
|
@ -18,13 +18,12 @@ class EventChainPostVisitor;
|
|||
class EventChainPreVisitor;
|
||||
namespace dom {
|
||||
|
||||
typedef nsMappedAttributeElement MathMLElementBase;
|
||||
using MathMLElementBase = nsStyledElement;
|
||||
|
||||
/*
|
||||
* The base class for MathML elements.
|
||||
*/
|
||||
class MathMLElement final : public MathMLElementBase,
|
||||
public mozilla::dom::Link {
|
||||
class MathMLElement final : public MathMLElementBase, public Link {
|
||||
public:
|
||||
explicit MathMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
|
||||
explicit MathMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
|
||||
|
@ -56,8 +55,9 @@ class MathMLElement final : public MathMLElementBase,
|
|||
static bool ParseNumericValue(const nsString& aString, nsCSSValue& aCSSValue,
|
||||
uint32_t aFlags, Document* aDocument);
|
||||
|
||||
static void MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
|
||||
mozilla::MappedDeclarations&);
|
||||
static void MapGlobalMathMLAttributesInto(
|
||||
mozilla::MappedDeclarationsBuilder&);
|
||||
static void MapMTableAttributesInto(mozilla::MappedDeclarationsBuilder&);
|
||||
|
||||
void GetEventTargetParent(mozilla::EventChainPreVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/DeclarationBlock.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/InternalMutationEvent.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
|
@ -105,9 +104,7 @@ SVGEnumMapping SVGElement::sSVGUnitTypesMap[] = {
|
|||
SVGElement::SVGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: SVGElementBase(std::move(aNodeInfo)) {}
|
||||
|
||||
SVGElement::~SVGElement() {
|
||||
OwnerDoc()->UnscheduleSVGForPresAttrEvaluation(this);
|
||||
}
|
||||
SVGElement::~SVGElement() = default;
|
||||
|
||||
JSObject* SVGElement::WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
|
@ -317,23 +314,6 @@ void SVGElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
|||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue,
|
||||
nsIPrincipal* aSubjectPrincipal, bool aNotify) {
|
||||
// We don't currently use nsMappedAttributes within SVG. If this changes, we
|
||||
// need to be very careful because some nsAttrValues used by SVG point to
|
||||
// member data of SVG elements and if an nsAttrValue outlives the SVG element
|
||||
// whose data it points to (by virtue of being stored in
|
||||
// mAttrs->mMappedAttributes, meaning it's shared between
|
||||
// elements), the pointer will dangle. See bug 724680.
|
||||
MOZ_ASSERT(!mAttrs.HasMappedAttrs(),
|
||||
"Unexpected use of nsMappedAttributes within SVG");
|
||||
|
||||
// If this is an svg presentation attribute we need to map it into
|
||||
// the content declaration block.
|
||||
// XXX For some reason incremental mapping doesn't work, so for now
|
||||
// just delete the style rule and lazily reconstruct it as needed).
|
||||
if (aNamespaceID == kNameSpaceID_None && IsAttributeMapped(aName)) {
|
||||
OwnerDoc()->ScheduleSVGForPresAttrEvaluation(this);
|
||||
}
|
||||
|
||||
if (IsEventAttributeName(aName) && aValue) {
|
||||
MOZ_ASSERT(aValue->Type() == nsAttrValue::eString,
|
||||
"Expected string value for script body");
|
||||
|
@ -925,9 +905,6 @@ nsChangeHint SVGElement::GetAttributeChangeHint(const nsAtom* aAttribute,
|
|||
|
||||
void SVGElement::NodeInfoChanged(Document* aOldDoc) {
|
||||
SVGElementBase::NodeInfoChanged(aOldDoc);
|
||||
aOldDoc->UnscheduleSVGForPresAttrEvaluation(this);
|
||||
mContentDeclarationBlock = nullptr;
|
||||
OwnerDoc()->ScheduleSVGForPresAttrEvaluation(this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
|
@ -1042,10 +1019,8 @@ already_AddRefed<DOMSVGAnimatedString> SVGElement::ClassName() {
|
|||
|
||||
/* static */
|
||||
bool SVGElement::UpdateDeclarationBlockFromLength(
|
||||
DeclarationBlock& aBlock, nsCSSPropertyID aPropId,
|
||||
StyleLockedDeclarationBlock& aBlock, nsCSSPropertyID aPropId,
|
||||
const SVGAnimatedLength& aLength, ValToUse aValToUse) {
|
||||
aBlock.AssertMutable();
|
||||
|
||||
float value;
|
||||
if (aValToUse == ValToUse::Anim) {
|
||||
value = aLength.GetAnimValInSpecifiedUnits();
|
||||
|
@ -1054,8 +1029,8 @@ bool SVGElement::UpdateDeclarationBlockFromLength(
|
|||
value = aLength.GetBaseValInSpecifiedUnits();
|
||||
}
|
||||
|
||||
// SVG parser doesn't check non-negativity of some parsed value,
|
||||
// we should not pass those to CSS side.
|
||||
// SVG parser doesn't check non-negativity of some parsed value, we should not
|
||||
// pass those to CSS side.
|
||||
if (value < 0 &&
|
||||
SVGGeometryProperty::IsNonNegativeGeometryProperty(aPropId)) {
|
||||
return false;
|
||||
|
@ -1065,11 +1040,9 @@ bool SVGElement::UpdateDeclarationBlockFromLength(
|
|||
SVGLength::SpecifiedUnitTypeToCSSUnit(aLength.GetSpecifiedUnitType());
|
||||
|
||||
if (cssUnit == eCSSUnit_Percent) {
|
||||
Servo_DeclarationBlock_SetPercentValue(aBlock.Raw(), aPropId,
|
||||
value / 100.f);
|
||||
Servo_DeclarationBlock_SetPercentValue(&aBlock, aPropId, value / 100.f);
|
||||
} else {
|
||||
Servo_DeclarationBlock_SetLengthValue(aBlock.Raw(), aPropId, value,
|
||||
cssUnit);
|
||||
Servo_DeclarationBlock_SetLengthValue(&aBlock, aPropId, value, cssUnit);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1077,10 +1050,8 @@ bool SVGElement::UpdateDeclarationBlockFromLength(
|
|||
|
||||
/* static */
|
||||
bool SVGElement::UpdateDeclarationBlockFromPath(
|
||||
DeclarationBlock& aBlock, const SVGAnimatedPathSegList& aPath,
|
||||
StyleLockedDeclarationBlock& aBlock, const SVGAnimatedPathSegList& aPath,
|
||||
ValToUse aValToUse) {
|
||||
aBlock.AssertMutable();
|
||||
|
||||
const SVGPathData& pathData =
|
||||
aValToUse == ValToUse::Anim ? aPath.GetAnimValue() : aPath.GetBaseValue();
|
||||
|
||||
|
@ -1095,7 +1066,7 @@ bool SVGElement::UpdateDeclarationBlockFromPath(
|
|||
// The normalization should be fixed in Bug 1489392. Besides, Bug 1714238
|
||||
// will use the same data structure, so we may simplify this more.
|
||||
const nsTArray<float>& asInFallibleArray = pathData.RawData();
|
||||
Servo_DeclarationBlock_SetPathValue(aBlock.Raw(), eCSSProperty_d,
|
||||
Servo_DeclarationBlock_SetPathValue(&aBlock, eCSSProperty_d,
|
||||
&asInFallibleArray);
|
||||
return true;
|
||||
}
|
||||
|
@ -1108,11 +1079,10 @@ namespace {
|
|||
class MOZ_STACK_CLASS MappedAttrParser {
|
||||
public:
|
||||
explicit MappedAttrParser(SVGElement& aElement,
|
||||
already_AddRefed<DeclarationBlock> aDecl)
|
||||
StyleLockedDeclarationBlock* aDecl)
|
||||
: mElement(aElement), mDecl(aDecl) {
|
||||
if (mDecl) {
|
||||
mDecl->AssertMutable();
|
||||
Servo_DeclarationBlock_Clear(mDecl->Raw());
|
||||
Servo_DeclarationBlock_Clear(mDecl);
|
||||
}
|
||||
}
|
||||
~MappedAttrParser() {
|
||||
|
@ -1130,15 +1100,15 @@ class MOZ_STACK_CLASS MappedAttrParser {
|
|||
void TellStyleAlreadyParsedResult(const SVGAnimatedPathSegList& aPath);
|
||||
|
||||
// If we've parsed any values for mapped attributes, this method returns the
|
||||
// already_AddRefed css::Declaration that incorporates the parsed
|
||||
// values. Otherwise, this method returns null.
|
||||
already_AddRefed<DeclarationBlock> TakeDeclarationBlock() {
|
||||
// already_AddRefed declaration block that incorporates the parsed values.
|
||||
// Otherwise, this method returns null.
|
||||
already_AddRefed<StyleLockedDeclarationBlock> TakeDeclarationBlock() {
|
||||
return mDecl.forget();
|
||||
}
|
||||
|
||||
DeclarationBlock& EnsureDeclarationBlock() {
|
||||
StyleLockedDeclarationBlock& EnsureDeclarationBlock() {
|
||||
if (!mDecl) {
|
||||
mDecl = new DeclarationBlock();
|
||||
mDecl = Servo_DeclarationBlock_CreateEmpty().Consume();
|
||||
}
|
||||
return *mDecl;
|
||||
}
|
||||
|
@ -1155,7 +1125,7 @@ class MOZ_STACK_CLASS MappedAttrParser {
|
|||
SVGElement& mElement;
|
||||
|
||||
// Declaration for storing parsed values (lazily initialized).
|
||||
RefPtr<DeclarationBlock> mDecl;
|
||||
RefPtr<StyleLockedDeclarationBlock> mDecl;
|
||||
|
||||
// URL data for parsing stuff. Also lazy.
|
||||
RefPtr<URLExtraData> mExtraData;
|
||||
|
@ -1172,7 +1142,7 @@ void MappedAttrParser::ParseMappedAttrValue(nsAtom* aMappedAttrName,
|
|||
|
||||
auto* doc = mElement.OwnerDoc();
|
||||
changed = Servo_DeclarationBlock_SetPropertyById(
|
||||
EnsureDeclarationBlock().Raw(), propertyID, &value, false,
|
||||
&EnsureDeclarationBlock(), propertyID, &value, false,
|
||||
&EnsureExtraData(), ParsingMode::AllowUnitlessLength,
|
||||
doc->GetCompatibilityMode(), doc->CSSLoader(), StyleCssRuleType::Style,
|
||||
{});
|
||||
|
@ -1193,7 +1163,7 @@ void MappedAttrParser::ParseMappedAttrValue(nsAtom* aMappedAttrName,
|
|||
if (aMappedAttrName == nsGkAtoms::lang) {
|
||||
propertyID = eCSSProperty__x_lang;
|
||||
RefPtr<nsAtom> atom = NS_Atomize(aMappedAttrValue);
|
||||
Servo_DeclarationBlock_SetIdentStringValue(EnsureDeclarationBlock().Raw(),
|
||||
Servo_DeclarationBlock_SetIdentStringValue(&EnsureDeclarationBlock(),
|
||||
propertyID, atom);
|
||||
}
|
||||
}
|
||||
|
@ -1218,10 +1188,11 @@ void MappedAttrParser::TellStyleAlreadyParsedResult(
|
|||
//----------------------------------------------------------------------
|
||||
// Implementation Helpers:
|
||||
|
||||
void SVGElement::UpdateContentDeclarationBlock() {
|
||||
MappedAttrParser mappedAttrParser(*this, mContentDeclarationBlock.forget());
|
||||
void SVGElement::UpdateMappedDeclarationBlock() {
|
||||
MOZ_ASSERT(IsPendingMappedAttributeEvaluation());
|
||||
MappedAttrParser mappedAttrParser(*this, mAttrs.GetMappedDeclarationBlock());
|
||||
|
||||
bool lengthAffectsStyle =
|
||||
const bool lengthAffectsStyle =
|
||||
SVGGeometryProperty::ElementMapsLengthsToStyle(this);
|
||||
|
||||
uint32_t i = 0;
|
||||
|
@ -1279,7 +1250,7 @@ void SVGElement::UpdateContentDeclarationBlock() {
|
|||
info.mValue->ToString(value);
|
||||
mappedAttrParser.ParseMappedAttrValue(attrName->Atom(), value);
|
||||
}
|
||||
mContentDeclarationBlock = mappedAttrParser.TakeDeclarationBlock();
|
||||
mAttrs.SetMappedDeclarationBlock(mappedAttrParser.TakeDeclarationBlock());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2371,16 +2342,6 @@ void SVGElement::FlushAnimations() {
|
|||
void SVGElement::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
|
||||
size_t* aNodeSize) const {
|
||||
Element::AddSizeOfExcludingThis(aSizes, aNodeSize);
|
||||
|
||||
// These are owned by the element and not referenced from the stylesheets.
|
||||
// They're referenced from the rule tree, but the rule nodes don't measure
|
||||
// their style source (since they're non-owning), so unconditionally reporting
|
||||
// them even though it's a refcounted object is ok.
|
||||
if (mContentDeclarationBlock) {
|
||||
aSizes.mLayoutSvgMappedDeclarations +=
|
||||
mContentDeclarationBlock->SizeofIncludingThis(
|
||||
aSizes.mState.mMallocSizeOf);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -42,7 +42,6 @@ nsresult NS_NewSVGElement(mozilla::dom::Element** aResult,
|
|||
class mozAutoDocUpdate;
|
||||
|
||||
namespace mozilla {
|
||||
class DeclarationBlock;
|
||||
|
||||
class SVGAnimatedBoolean;
|
||||
class SVGAnimatedEnumeration;
|
||||
|
@ -126,6 +125,7 @@ class SVGElement : public SVGElementBase // nsIContent
|
|||
void NodeInfoChanged(Document* aOldDoc) override;
|
||||
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
void UpdateMappedDeclarationBlock();
|
||||
|
||||
NS_IMPL_FROMNODE(SVGElement, kNameSpaceID_SVG)
|
||||
|
||||
|
@ -181,12 +181,11 @@ class SVGElement : public SVGElementBase // nsIContent
|
|||
void SetLength(nsAtom* aName, const SVGAnimatedLength& aLength);
|
||||
|
||||
enum class ValToUse { Base, Anim };
|
||||
static bool UpdateDeclarationBlockFromLength(DeclarationBlock& aBlock,
|
||||
nsCSSPropertyID aPropId,
|
||||
const SVGAnimatedLength& aLength,
|
||||
ValToUse aValToUse);
|
||||
static bool UpdateDeclarationBlockFromLength(
|
||||
StyleLockedDeclarationBlock& aBlock, nsCSSPropertyID aPropId,
|
||||
const SVGAnimatedLength& aLength, ValToUse aValToUse);
|
||||
static bool UpdateDeclarationBlockFromPath(
|
||||
DeclarationBlock& aBlock, const SVGAnimatedPathSegList& aPath,
|
||||
StyleLockedDeclarationBlock& aBlock, const SVGAnimatedPathSegList& aPath,
|
||||
ValToUse aValToUse);
|
||||
|
||||
nsAttrValue WillChangeLength(uint8_t aAttrEnum,
|
||||
|
@ -331,11 +330,6 @@ class SVGElement : public SVGElementBase // nsIContent
|
|||
SVGElement* GetViewportElement();
|
||||
already_AddRefed<mozilla::dom::DOMSVGAnimatedString> ClassName();
|
||||
|
||||
void UpdateContentDeclarationBlock();
|
||||
const mozilla::DeclarationBlock* GetContentDeclarationBlock() const {
|
||||
return mContentDeclarationBlock.get();
|
||||
}
|
||||
|
||||
bool Autofocus() const { return GetBoolAttr(nsGkAtoms::autofocus); }
|
||||
void SetAutofocus(bool aAutofocus, ErrorResult& aRv) {
|
||||
if (aAutofocus) {
|
||||
|
@ -515,7 +509,6 @@ class SVGElement : public SVGElementBase // nsIContent
|
|||
|
||||
SVGAnimatedClass mClassAttribute;
|
||||
UniquePtr<nsAttrValue> mClassAnimAttr;
|
||||
RefPtr<mozilla::DeclarationBlock> mContentDeclarationBlock;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(SVGElement, MOZILLA_SVGELEMENT_IID)
|
||||
|
|
|
@ -90,7 +90,7 @@ SimpleTest.waitForFocus(() => {
|
|||
SpecialPowers.doCommand(window, "cmd_backgroundColor", "#00ff00");
|
||||
is(
|
||||
editor.outerHTML,
|
||||
"<div style=\"background-color: rgb(255, 0, 0);\" contenteditable=\"\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p></div></div>",
|
||||
"<div contenteditable=\"\" style=\"background-color: rgb(255, 0, 0);\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p></div></div>",
|
||||
"cmd_backgroundColor should set background of the closest block element from the caret in a text node"
|
||||
);
|
||||
|
||||
|
@ -102,7 +102,7 @@ SimpleTest.waitForFocus(() => {
|
|||
SpecialPowers.doCommand(window, "cmd_backgroundColor", "#00ff00");
|
||||
is(
|
||||
editor.outerHTML,
|
||||
"<div style=\"background-color: rgb(0, 255, 0);\" contenteditable=\"\">abc</div>",
|
||||
"<div contenteditable=\"\" style=\"background-color: rgb(0, 255, 0);\">abc</div>",
|
||||
"cmd_backgroundColor should set background of the editing host which is direct block parent from the caret in a text node"
|
||||
);
|
||||
|
||||
|
@ -114,7 +114,7 @@ SimpleTest.waitForFocus(() => {
|
|||
SpecialPowers.doCommand(window, "cmd_backgroundColor", "#00ff00");
|
||||
is(
|
||||
editor.outerHTML,
|
||||
"<div style=\"background-color: rgb(255, 0, 0);\" contenteditable=\"\"><div contenteditable=\"false\"><span contenteditable=\"true\">abc</span></div></div>",
|
||||
"<div contenteditable=\"\" style=\"background-color: rgb(255, 0, 0);\"><div contenteditable=\"false\"><span contenteditable=\"true\">abc</span></div></div>",
|
||||
"cmd_backgroundColor should not set background color of inline editing host nor its non-editable parent block"
|
||||
);
|
||||
|
||||
|
@ -126,7 +126,7 @@ SimpleTest.waitForFocus(() => {
|
|||
SpecialPowers.doCommand(window, "cmd_backgroundColor", "#00ff00");
|
||||
is(
|
||||
editor.outerHTML,
|
||||
"<div style=\"background-color: rgb(255, 0, 0);\" contenteditable=\"\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>ab<br>c</span></p></div></div>",
|
||||
"<div contenteditable=\"\" style=\"background-color: rgb(255, 0, 0);\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>ab<br>c</span></p></div></div>",
|
||||
"cmd_backgroundColor should set background of the closest block element when selection a leaf element"
|
||||
);
|
||||
|
||||
|
@ -138,7 +138,7 @@ SimpleTest.waitForFocus(() => {
|
|||
SpecialPowers.doCommand(window, "cmd_backgroundColor", "#00ff00");
|
||||
is(
|
||||
editor.outerHTML,
|
||||
"<div style=\"background-color: rgb(255, 0, 0);\" contenteditable=\"\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p></div></div>",
|
||||
"<div contenteditable=\"\" style=\"background-color: rgb(255, 0, 0);\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p></div></div>",
|
||||
"cmd_backgroundColor should set background of the selected block element"
|
||||
);
|
||||
|
||||
|
@ -150,7 +150,7 @@ SimpleTest.waitForFocus(() => {
|
|||
SpecialPowers.doCommand(window, "cmd_backgroundColor", "#00ff00");
|
||||
is(
|
||||
editor.outerHTML,
|
||||
"<div style=\"background-color: rgb(255, 0, 0);\" contenteditable=\"\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p>" +
|
||||
"<div contenteditable=\"\" style=\"background-color: rgb(255, 0, 0);\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p>" +
|
||||
"<p style=\"background-color: rgb(0, 255, 0);\"><span>def</span></p>" +
|
||||
"<p style=\"background-color: rgb(0, 255, 0);\"><span>ghi</span></p></div></div>",
|
||||
"cmd_backgroundColor should set background of the paragraph elements in the selection range"
|
||||
|
@ -164,7 +164,7 @@ SimpleTest.waitForFocus(() => {
|
|||
SpecialPowers.doCommand(window, "cmd_backgroundColor", "#00ff00");
|
||||
is(
|
||||
editor.outerHTML,
|
||||
"<div style=\"background-color: rgb(255, 0, 0);\" contenteditable=\"\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p>" +
|
||||
"<div contenteditable=\"\" style=\"background-color: rgb(255, 0, 0);\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p>" +
|
||||
"<p style=\"background-color: rgb(0, 255, 0);\"><span contenteditable=\"false\">def</span></p>" +
|
||||
"<p style=\"background-color: rgb(0, 255, 0);\"><span>ghi</span></p></div></div>",
|
||||
"cmd_backgroundColor should set background of the paragraph elements in the selection range even if a paragraph has only non-editable content"
|
||||
|
@ -178,7 +178,7 @@ SimpleTest.waitForFocus(() => {
|
|||
SpecialPowers.doCommand(window, "cmd_backgroundColor", "#00ff00");
|
||||
is(
|
||||
editor.outerHTML,
|
||||
"<div style=\"background-color: rgb(255, 0, 0);\" contenteditable=\"\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p>" +
|
||||
"<div contenteditable=\"\" style=\"background-color: rgb(255, 0, 0);\"><div><p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p>" +
|
||||
"<p contenteditable=\"false\"><span>def</span></p>" +
|
||||
"<p style=\"background-color: rgb(0, 255, 0);\"><span>ghi</span></p></div></div>",
|
||||
"cmd_backgroundColor should set background of the paragraph elements in the selection range except the non-editable paragraph"
|
||||
|
@ -192,7 +192,7 @@ SimpleTest.waitForFocus(() => {
|
|||
SpecialPowers.doCommand(window, "cmd_backgroundColor", "#00ff00");
|
||||
is(
|
||||
editor.outerHTML,
|
||||
"<div style=\"background-color: rgb(255, 0, 0);\" contenteditable=\"\"><div style=\"background-color: rgb(0, 255, 0);\">" +
|
||||
"<div contenteditable=\"\" style=\"background-color: rgb(255, 0, 0);\"><div style=\"background-color: rgb(0, 255, 0);\">" +
|
||||
"<p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p>" +
|
||||
"<span>def</span>" +
|
||||
"<p style=\"background-color: rgb(0, 255, 0);\"><span>ghi</span></p></div></div>",
|
||||
|
@ -207,7 +207,7 @@ SimpleTest.waitForFocus(() => {
|
|||
SpecialPowers.doCommand(window, "cmd_backgroundColor", "#00ff00");
|
||||
is(
|
||||
editor.outerHTML,
|
||||
"<div style=\"background-color: rgb(0, 255, 0);\" contenteditable=\"\">" +
|
||||
"<div contenteditable=\"\" style=\"background-color: rgb(0, 255, 0);\">" +
|
||||
"<p style=\"background-color: rgb(0, 255, 0);\"><span>abc</span></p>" +
|
||||
"<span>def</span>" +
|
||||
"<p style=\"background-color: rgb(0, 255, 0);\"><span>ghi</span></p></div>",
|
||||
|
|
|
@ -458,7 +458,7 @@ SimpleTest.waitForFocus(() => {
|
|||
range.selectNode(document.getElementById("select"));
|
||||
selection.addRange(range);
|
||||
getTableEditor().deleteTableRow(1);
|
||||
is(editor.innerHTML, '<table><tbody><tr><td rowspan="2" valign="top"><br></td><td>cell2-2</td></tr><tr><td>cell3-2</td></tr></tbody></table>',
|
||||
is(editor.innerHTML, '<table><tbody><tr><td valign="top" rowspan="2"><br></td><td>cell2-2</td></tr><tr><td>cell3-2</td></tr></tbody></table>',
|
||||
"nsITableEditor.deleteTableRow(1) with a selected cell is rowspan=\"3\" should delete the first row and add empty cell whose rowspan is 2 to the second row");
|
||||
is(beforeInputEvents.length, 1,
|
||||
'Only one "beforeinput" event should be fired when a cell is selected and its rowspan is 3');
|
||||
|
|
|
@ -3488,9 +3488,6 @@ void RestyleManager::AttributeChanged(Element* aElement, int32_t aNameSpaceID,
|
|||
restyleHint |= RestyleHint::RESTYLE_STYLE_ATTRIBUTE;
|
||||
} else if (AttributeChangeRequiresSubtreeRestyle(*aElement, aAttribute)) {
|
||||
restyleHint |= RestyleHint::RestyleSubtree();
|
||||
} else if (aElement->IsAttributeMapped(aAttribute)) {
|
||||
// FIXME(emilio): Does this really need to re-selector-match?
|
||||
restyleHint |= RestyleHint::RESTYLE_SELF;
|
||||
} else if (aElement->IsInShadowTree() && aAttribute == nsGkAtoms::part) {
|
||||
// TODO(emilio, bug 1598094): Maybe finer-grained invalidation for part
|
||||
// attribute changes?
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "mozilla/AttributeStyles.h"
|
||||
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
|
@ -31,45 +30,7 @@ namespace mozilla {
|
|||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
struct MappedAttrTableEntry : public PLDHashEntryHdr {
|
||||
nsMappedAttributes* mAttributes;
|
||||
};
|
||||
|
||||
static PLDHashNumber MappedAttrTable_HashKey(const void* key) {
|
||||
nsMappedAttributes* attributes =
|
||||
static_cast<nsMappedAttributes*>(const_cast<void*>(key));
|
||||
|
||||
return attributes->HashValue();
|
||||
}
|
||||
|
||||
static void MappedAttrTable_ClearEntry(PLDHashTable* table,
|
||||
PLDHashEntryHdr* hdr) {
|
||||
MappedAttrTableEntry* entry = static_cast<MappedAttrTableEntry*>(hdr);
|
||||
entry->mAttributes->DropAttributeStylesReference();
|
||||
memset(entry, 0, sizeof(MappedAttrTableEntry));
|
||||
}
|
||||
|
||||
static bool MappedAttrTable_MatchEntry(const PLDHashEntryHdr* hdr,
|
||||
const void* key) {
|
||||
nsMappedAttributes* attributes =
|
||||
static_cast<nsMappedAttributes*>(const_cast<void*>(key));
|
||||
const MappedAttrTableEntry* entry =
|
||||
static_cast<const MappedAttrTableEntry*>(hdr);
|
||||
|
||||
return attributes->Equals(entry->mAttributes);
|
||||
}
|
||||
|
||||
static const PLDHashTableOps MappedAttrTable_Ops = {
|
||||
MappedAttrTable_HashKey, MappedAttrTable_MatchEntry,
|
||||
PLDHashTable::MoveEntryStub, MappedAttrTable_ClearEntry, nullptr};
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
AttributeStyles::AttributeStyles(Document* aDocument)
|
||||
: mDocument(aDocument),
|
||||
mMappedAttrTable(&MappedAttrTable_Ops, sizeof(MappedAttrTableEntry)) {
|
||||
AttributeStyles::AttributeStyles(Document* aDocument) : mDocument(aDocument) {
|
||||
MOZ_ASSERT(aDocument);
|
||||
}
|
||||
|
||||
|
@ -81,9 +42,6 @@ void AttributeStyles::Reset() {
|
|||
mServoUnvisitedLinkDecl = nullptr;
|
||||
mServoVisitedLinkDecl = nullptr;
|
||||
mServoActiveLinkDecl = nullptr;
|
||||
|
||||
mMappedAttrTable.Clear();
|
||||
mMappedAttrsDirty = false;
|
||||
}
|
||||
|
||||
nsresult AttributeStyles::ImplLinkColorSetter(
|
||||
|
@ -117,54 +75,9 @@ nsresult AttributeStyles::SetVisitedLinkColor(nscolor aColor) {
|
|||
return ImplLinkColorSetter(mServoVisitedLinkDecl, aColor);
|
||||
}
|
||||
|
||||
already_AddRefed<nsMappedAttributes> AttributeStyles::UniqueMappedAttributes(
|
||||
nsMappedAttributes* aMapped) {
|
||||
mMappedAttrsDirty = true;
|
||||
auto entry = static_cast<MappedAttrTableEntry*>(
|
||||
mMappedAttrTable.Add(aMapped, fallible));
|
||||
if (!entry) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!entry->mAttributes) {
|
||||
// We added a new entry to the hashtable, so we have a new unique set.
|
||||
entry->mAttributes = aMapped;
|
||||
}
|
||||
RefPtr<nsMappedAttributes> ret = entry->mAttributes;
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
void AttributeStyles::DropMappedAttributes(nsMappedAttributes* aMapped) {
|
||||
NS_ENSURE_TRUE_VOID(aMapped);
|
||||
#ifdef DEBUG
|
||||
uint32_t entryCount = mMappedAttrTable.EntryCount() - 1;
|
||||
#endif
|
||||
|
||||
mMappedAttrTable.Remove(aMapped);
|
||||
|
||||
NS_ASSERTION(entryCount == mMappedAttrTable.EntryCount(), "not removed");
|
||||
}
|
||||
|
||||
void AttributeStyles::CalculateMappedServoDeclarations() {
|
||||
for (auto iter = mMappedAttrTable.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
MappedAttrTableEntry* attr = static_cast<MappedAttrTableEntry*>(iter.Get());
|
||||
if (attr->mAttributes->GetServoStyle()) {
|
||||
// Only handle cases which haven't been filled in already
|
||||
continue;
|
||||
}
|
||||
attr->mAttributes->LazilyResolveServoDeclaration(mDocument);
|
||||
}
|
||||
}
|
||||
|
||||
size_t AttributeStyles::DOMSizeOfIncludingThis(
|
||||
MallocSizeOf aMallocSizeOf) const {
|
||||
size_t n = aMallocSizeOf(this);
|
||||
|
||||
n += mMappedAttrTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
for (auto iter = mMappedAttrTable.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
auto entry = static_cast<MappedAttrTableEntry*>(iter.Get());
|
||||
n += entry->mAttributes->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
// Measurement of the following members may be added later if DMD finds it is
|
||||
// worthwhile:
|
||||
// - mServoUnvisitedLinkDecl;
|
||||
|
@ -173,7 +86,6 @@ size_t AttributeStyles::DOMSizeOfIncludingThis(
|
|||
//
|
||||
// The following members are not measured:
|
||||
// - mDocument, because it's non-owning
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "nsString.h"
|
||||
|
||||
struct MiscContainer;
|
||||
class nsMappedAttributes;
|
||||
namespace mozilla {
|
||||
struct StyleLockedDeclarationBlock;
|
||||
namespace dom {
|
||||
|
@ -53,14 +52,6 @@ class AttributeStyles final {
|
|||
return mServoActiveLinkDecl;
|
||||
}
|
||||
|
||||
// Mapped Attribute management methods
|
||||
already_AddRefed<nsMappedAttributes> UniqueMappedAttributes(
|
||||
nsMappedAttributes* aMapped);
|
||||
void DropMappedAttributes(nsMappedAttributes* aMapped);
|
||||
// For each mapped presentation attribute in the cache, resolve the attached
|
||||
// DeclarationBlock by running the mapping to Servo specified values.
|
||||
void CalculateMappedServoDeclarations();
|
||||
|
||||
void CacheStyleAttr(const nsAString& aSerialized, MiscContainer* aValue) {
|
||||
mCachedStyleAttrs.InsertOrUpdate(aSerialized, aValue);
|
||||
}
|
||||
|
@ -87,13 +78,7 @@ class AttributeStyles final {
|
|||
RefPtr<StyleLockedDeclarationBlock> mServoUnvisitedLinkDecl;
|
||||
RefPtr<StyleLockedDeclarationBlock> mServoVisitedLinkDecl;
|
||||
RefPtr<StyleLockedDeclarationBlock> mServoActiveLinkDecl;
|
||||
|
||||
PLDHashTable mMappedAttrTable;
|
||||
nsTHashMap<nsStringHashKey, MiscContainer*> mCachedStyleAttrs;
|
||||
// Whether or not the mapped attributes table
|
||||
// has been changed since the last call to
|
||||
// CalculateMappedServoDeclarations()
|
||||
bool mMappedAttrsDirty = false;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "nsINode.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
@ -391,29 +390,16 @@ void Gecko_UnsetDirtyStyleAttr(const Element* aElement) {
|
|||
|
||||
const StyleLockedDeclarationBlock*
|
||||
Gecko_GetHTMLPresentationAttrDeclarationBlock(const Element* aElement) {
|
||||
if (const nsMappedAttributes* attrs = aElement->GetMappedAttributes()) {
|
||||
MOZ_ASSERT(!aElement->IsSVGElement(), "SVG doesn't use nsMappedAttributes");
|
||||
return attrs->GetServoStyle();
|
||||
}
|
||||
if (const auto* svg = SVGElement::FromNode(aElement)) {
|
||||
if (const auto* decl = svg->GetContentDeclarationBlock()) {
|
||||
return decl->Raw();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return aElement->GetMappedAttributeStyle();
|
||||
}
|
||||
|
||||
const StyleLockedDeclarationBlock* Gecko_GetExtraContentStyleDeclarations(
|
||||
const Element* aElement) {
|
||||
if (const auto* cell = HTMLTableCellElement::FromNode(aElement)) {
|
||||
if (nsMappedAttributes* attrs =
|
||||
cell->GetMappedAttributesInheritedFromTable()) {
|
||||
return attrs->GetServoStyle();
|
||||
}
|
||||
} else if (const auto* img = HTMLImageElement::FromNode(aElement)) {
|
||||
if (const auto* attrs = img->GetMappedAttributesFromSource()) {
|
||||
return attrs->GetServoStyle();
|
||||
}
|
||||
return cell->GetMappedAttributesInheritedFromTable();
|
||||
}
|
||||
if (const auto* img = HTMLImageElement::FromNode(aElement)) {
|
||||
return img->GetMappedAttributesFromSource();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* 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/. */
|
||||
|
||||
#include "MappedDeclarations.h"
|
||||
#include "MappedDeclarationsBuilder.h"
|
||||
|
||||
#include "nsAttrValue.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
|
@ -13,9 +13,9 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
void MappedDeclarations::SetIdentAtomValue(nsCSSPropertyID aId,
|
||||
nsAtom* aValue) {
|
||||
Servo_DeclarationBlock_SetIdentStringValue(mDecl, aId, aValue);
|
||||
void MappedDeclarationsBuilder::SetIdentAtomValue(nsCSSPropertyID aId,
|
||||
nsAtom* aValue) {
|
||||
Servo_DeclarationBlock_SetIdentStringValue(&EnsureDecls(), aId, aValue);
|
||||
if (aId == eCSSProperty__x_lang) {
|
||||
// This forces the lang prefs result to be cached so that we can access them
|
||||
// off main thread during traversal.
|
||||
|
@ -23,11 +23,11 @@ void MappedDeclarations::SetIdentAtomValue(nsCSSPropertyID aId,
|
|||
// FIXME(emilio): Can we move mapped attribute declarations across
|
||||
// documents? Isn't this wrong in that case? This is pretty out of place
|
||||
// anyway.
|
||||
mDocument->ForceCacheLang(aValue);
|
||||
mDocument.ForceCacheLang(aValue);
|
||||
}
|
||||
}
|
||||
|
||||
void MappedDeclarations::SetBackgroundImage(const nsAttrValue& aValue) {
|
||||
void MappedDeclarationsBuilder::SetBackgroundImage(const nsAttrValue& aValue) {
|
||||
if (aValue.Type() != nsAttrValue::eURL) {
|
||||
return;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ void MappedDeclarations::SetBackgroundImage(const nsAttrValue& aValue) {
|
|||
nsAutoCString utf8;
|
||||
CopyUTF16toUTF8(str, utf8);
|
||||
Servo_DeclarationBlock_SetBackgroundImage(
|
||||
mDecl, &utf8, mDocument->DefaultStyleAttrURLData());
|
||||
&EnsureDecls(), &utf8, mDocument.DefaultStyleAttrURLData());
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -6,11 +6,12 @@
|
|||
|
||||
/* Representation of a declaration block used for attribute mapping */
|
||||
|
||||
#ifndef mozilla_MappedDeclarations_h
|
||||
#define mozilla_MappedDeclarations_h
|
||||
#ifndef mozilla_MappedDeclarationsBuilder_h
|
||||
#define mozilla_MappedDeclarationsBuilder_h
|
||||
|
||||
#include "mozilla/FontPropertyTypes.h"
|
||||
#include "mozilla/ServoBindingTypes.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/ServoBindings.h"
|
||||
#include "nsCSSPropertyID.h"
|
||||
#include "nsCSSValue.h"
|
||||
|
@ -23,26 +24,30 @@ namespace mozilla {
|
|||
// This provides a convenient interface for attribute mappers
|
||||
// (MapAttributesIntoRule) to modify the presentation attribute declaration
|
||||
// block for a given element.
|
||||
class MappedDeclarations final {
|
||||
class MOZ_STACK_CLASS MappedDeclarationsBuilder final {
|
||||
public:
|
||||
explicit MappedDeclarations(
|
||||
dom::Document* aDoc, already_AddRefed<StyleLockedDeclarationBlock> aDecls)
|
||||
: mDocument(aDoc), mDecl(aDecls) {
|
||||
MOZ_ASSERT(mDecl);
|
||||
explicit MappedDeclarationsBuilder(
|
||||
dom::Element& aElement, dom::Document& aDoc,
|
||||
StyleLockedDeclarationBlock* aDecls = nullptr)
|
||||
: mDocument(aDoc), mElement(aElement), mDecls(aDecls) {
|
||||
if (mDecls) {
|
||||
Servo_DeclarationBlock_Clear(mDecls);
|
||||
}
|
||||
}
|
||||
|
||||
~MappedDeclarations() { MOZ_ASSERT(!mDecl, "Forgot to take the block?"); }
|
||||
~MappedDeclarationsBuilder() {
|
||||
MOZ_ASSERT(!mDecls, "Forgot to take the block?");
|
||||
}
|
||||
|
||||
dom::Document* Document() { return mDocument; }
|
||||
dom::Document& Document() { return mDocument; }
|
||||
|
||||
already_AddRefed<StyleLockedDeclarationBlock> TakeDeclarationBlock() {
|
||||
MOZ_ASSERT(mDecl);
|
||||
return mDecl.forget();
|
||||
return mDecls.forget();
|
||||
}
|
||||
|
||||
// Check if we already contain a certain longhand
|
||||
bool PropertyIsSet(nsCSSPropertyID aId) const {
|
||||
return Servo_DeclarationBlock_PropertyIsSet(mDecl, aId);
|
||||
return mDecls && Servo_DeclarationBlock_PropertyIsSet(mDecls, aId);
|
||||
}
|
||||
|
||||
// Set a property to an identifier (string)
|
||||
|
@ -67,7 +72,7 @@ class MappedDeclarations final {
|
|||
|
||||
// Set a property to a keyword (usually NS_STYLE_* or StyleFoo::*)
|
||||
void SetKeywordValue(nsCSSPropertyID aId, int32_t aValue) {
|
||||
Servo_DeclarationBlock_SetKeywordValue(mDecl, aId, aValue);
|
||||
Servo_DeclarationBlock_SetKeywordValue(&EnsureDecls(), aId, aValue);
|
||||
}
|
||||
|
||||
void SetKeywordValueIfUnset(nsCSSPropertyID aId, int32_t aValue) {
|
||||
|
@ -93,28 +98,30 @@ class MappedDeclarations final {
|
|||
|
||||
// Set a property to an integer value
|
||||
void SetIntValue(nsCSSPropertyID aId, int32_t aValue) {
|
||||
Servo_DeclarationBlock_SetIntValue(mDecl, aId, aValue);
|
||||
Servo_DeclarationBlock_SetIntValue(&EnsureDecls(), aId, aValue);
|
||||
}
|
||||
|
||||
// Set "math-depth: <integer>" or "math-depth: add(<integer>)"
|
||||
void SetMathDepthValue(int32_t aValue, bool aIsRelative) {
|
||||
Servo_DeclarationBlock_SetMathDepthValue(mDecl, aValue, aIsRelative);
|
||||
Servo_DeclarationBlock_SetMathDepthValue(&EnsureDecls(), aValue,
|
||||
aIsRelative);
|
||||
}
|
||||
|
||||
// Set "counter-reset: list-item <integer>". If aIsReversed is true then
|
||||
// "list-item" instead becomes "reversed(list-item)".
|
||||
void SetCounterResetListItem(int32_t aValue, bool aIsReversed) {
|
||||
Servo_DeclarationBlock_SetCounterResetListItem(mDecl, aValue, aIsReversed);
|
||||
Servo_DeclarationBlock_SetCounterResetListItem(&EnsureDecls(), aValue,
|
||||
aIsReversed);
|
||||
}
|
||||
|
||||
// Set "counter-set: list-item <integer>".
|
||||
void SetCounterSetListItem(int32_t aValue) {
|
||||
Servo_DeclarationBlock_SetCounterSetListItem(mDecl, aValue);
|
||||
Servo_DeclarationBlock_SetCounterSetListItem(&EnsureDecls(), aValue);
|
||||
}
|
||||
|
||||
// Set a property to a pixel value
|
||||
void SetPixelValue(nsCSSPropertyID aId, float aValue) {
|
||||
Servo_DeclarationBlock_SetPixelValue(mDecl, aId, aValue);
|
||||
Servo_DeclarationBlock_SetPixelValue(&EnsureDecls(), aId, aValue);
|
||||
}
|
||||
|
||||
void SetPixelValueIfUnset(nsCSSPropertyID aId, float aValue) {
|
||||
|
@ -125,18 +132,18 @@ class MappedDeclarations final {
|
|||
|
||||
void SetLengthValue(nsCSSPropertyID aId, const nsCSSValue& aValue) {
|
||||
MOZ_ASSERT(aValue.IsLengthUnit());
|
||||
Servo_DeclarationBlock_SetLengthValue(mDecl, aId, aValue.GetFloatValue(),
|
||||
aValue.GetUnit());
|
||||
Servo_DeclarationBlock_SetLengthValue(
|
||||
&EnsureDecls(), aId, aValue.GetFloatValue(), aValue.GetUnit());
|
||||
}
|
||||
|
||||
// Set a property to a number value
|
||||
void SetNumberValue(nsCSSPropertyID aId, float aValue) {
|
||||
Servo_DeclarationBlock_SetNumberValue(mDecl, aId, aValue);
|
||||
Servo_DeclarationBlock_SetNumberValue(&EnsureDecls(), aId, aValue);
|
||||
}
|
||||
|
||||
// Set a property to a percent value
|
||||
void SetPercentValue(nsCSSPropertyID aId, float aValue) {
|
||||
Servo_DeclarationBlock_SetPercentValue(mDecl, aId, aValue);
|
||||
Servo_DeclarationBlock_SetPercentValue(&EnsureDecls(), aId, aValue);
|
||||
}
|
||||
|
||||
void SetPercentValueIfUnset(nsCSSPropertyID aId, float aValue) {
|
||||
|
@ -147,7 +154,7 @@ class MappedDeclarations final {
|
|||
|
||||
// Set a property to `auto`
|
||||
void SetAutoValue(nsCSSPropertyID aId) {
|
||||
Servo_DeclarationBlock_SetAutoValue(mDecl, aId);
|
||||
Servo_DeclarationBlock_SetAutoValue(&EnsureDecls(), aId);
|
||||
}
|
||||
|
||||
void SetAutoValueIfUnset(nsCSSPropertyID aId) {
|
||||
|
@ -158,7 +165,7 @@ class MappedDeclarations final {
|
|||
|
||||
// Set a property to `currentcolor`
|
||||
void SetCurrentColor(nsCSSPropertyID aId) {
|
||||
Servo_DeclarationBlock_SetCurrentColor(mDecl, aId);
|
||||
Servo_DeclarationBlock_SetCurrentColor(&EnsureDecls(), aId);
|
||||
}
|
||||
|
||||
void SetCurrentColorIfUnset(nsCSSPropertyID aId) {
|
||||
|
@ -169,7 +176,7 @@ class MappedDeclarations final {
|
|||
|
||||
// Set a property to an RGBA nscolor value
|
||||
void SetColorValue(nsCSSPropertyID aId, nscolor aValue) {
|
||||
Servo_DeclarationBlock_SetColorValue(mDecl, aId, aValue);
|
||||
Servo_DeclarationBlock_SetColorValue(&EnsureDecls(), aId, aValue);
|
||||
}
|
||||
|
||||
void SetColorValueIfUnset(nsCSSPropertyID aId, nscolor aValue) {
|
||||
|
@ -180,26 +187,39 @@ class MappedDeclarations final {
|
|||
|
||||
// Set font-family to a string
|
||||
void SetFontFamily(const nsACString& aValue) {
|
||||
Servo_DeclarationBlock_SetFontFamily(mDecl, &aValue);
|
||||
Servo_DeclarationBlock_SetFontFamily(&EnsureDecls(), &aValue);
|
||||
}
|
||||
|
||||
// Add a quirks-mode override to the decoration color of elements nested in
|
||||
// <a>
|
||||
void SetTextDecorationColorOverride() {
|
||||
Servo_DeclarationBlock_SetTextDecorationColorOverride(mDecl);
|
||||
Servo_DeclarationBlock_SetTextDecorationColorOverride(&EnsureDecls());
|
||||
}
|
||||
|
||||
void SetBackgroundImage(const nsAttrValue& value);
|
||||
|
||||
void SetAspectRatio(float aWidth, float aHeight) {
|
||||
Servo_DeclarationBlock_SetAspectRatio(mDecl, aWidth, aHeight);
|
||||
Servo_DeclarationBlock_SetAspectRatio(&EnsureDecls(), aWidth, aHeight);
|
||||
}
|
||||
|
||||
const nsAttrValue* GetAttr(nsAtom* aName) {
|
||||
MOZ_ASSERT(mElement.IsAttributeMapped(aName));
|
||||
return mElement.GetParsedAttr(aName);
|
||||
}
|
||||
|
||||
private:
|
||||
dom::Document* const mDocument;
|
||||
RefPtr<StyleLockedDeclarationBlock> mDecl;
|
||||
StyleLockedDeclarationBlock& EnsureDecls() {
|
||||
if (!mDecls) {
|
||||
mDecls = Servo_DeclarationBlock_CreateEmpty().Consume();
|
||||
}
|
||||
return *mDecls;
|
||||
}
|
||||
|
||||
dom::Document& mDocument;
|
||||
dom::Element& mElement;
|
||||
RefPtr<StyleLockedDeclarationBlock> mDecls;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_MappedDeclarations_h
|
||||
#endif
|
|
@ -34,7 +34,6 @@ headers = [
|
|||
"mozilla/ServoTraversalStatistics.h",
|
||||
"mozilla/SizeOfState.h",
|
||||
"nsCSSProps.h",
|
||||
"nsMappedAttributes.h",
|
||||
"nsNameSpaceManager.h",
|
||||
]
|
||||
raw-lines = [
|
||||
|
|
|
@ -321,14 +321,6 @@ const ServoElementSnapshotTable& ServoStyleSet::Snapshots() {
|
|||
return GetPresContext()->RestyleManager()->Snapshots();
|
||||
}
|
||||
|
||||
void ServoStyleSet::ResolveMappedAttrDeclarationBlocks() {
|
||||
if (AttributeStyles* attrStyles = mDocument->GetAttributeStyles()) {
|
||||
attrStyles->CalculateMappedServoDeclarations();
|
||||
}
|
||||
|
||||
mDocument->ResolveScheduledSVGPresAttrs();
|
||||
}
|
||||
|
||||
void ServoStyleSet::PreTraverseSync() {
|
||||
// Get the Document's root element to ensure that the cache is valid before
|
||||
// calling into the (potentially-parallel) Servo traversal, where a cache hit
|
||||
|
@ -341,7 +333,7 @@ void ServoStyleSet::PreTraverseSync() {
|
|||
// can end up doing editing stuff, which adds stylesheets etc...
|
||||
mDocument->FlushUserFontSet();
|
||||
|
||||
ResolveMappedAttrDeclarationBlocks();
|
||||
mDocument->ResolveScheduledPresAttrs();
|
||||
|
||||
LookAndFeel::NativeInit();
|
||||
|
||||
|
|
|
@ -552,14 +552,6 @@ class ServoStyleSet {
|
|||
*/
|
||||
const SnapshotTable& Snapshots();
|
||||
|
||||
/**
|
||||
* Resolve all DeclarationBlocks attached to mapped
|
||||
* presentation attributes cached on the document.
|
||||
*
|
||||
* Call this before jumping into Servo's style system.
|
||||
*/
|
||||
void ResolveMappedAttrDeclarationBlocks();
|
||||
|
||||
/**
|
||||
* Clear our cached mNonInheritingComputedStyles.
|
||||
*
|
||||
|
|
|
@ -81,7 +81,7 @@ EXPORTS.mozilla += [
|
|||
"GlobalStyleSheetCache.h",
|
||||
"ImportScanner.h",
|
||||
"LayerAnimationInfo.h",
|
||||
"MappedDeclarations.h",
|
||||
"MappedDeclarationsBuilder.h",
|
||||
"MediaFeatureChange.h",
|
||||
"PostTraversalTask.h",
|
||||
"PreferenceSheet.h",
|
||||
|
@ -208,7 +208,7 @@ UNIFIED_SOURCES += [
|
|||
"ImportScanner.cpp",
|
||||
"LayerAnimationInfo.cpp",
|
||||
"Loader.cpp",
|
||||
"MappedDeclarations.cpp",
|
||||
"MappedDeclarationsBuilder.cpp",
|
||||
"MediaList.cpp",
|
||||
"MediaQueryList.cpp",
|
||||
"nsAnimationManager.cpp",
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
To change the list of properties, see ServoCSSPropList.h
|
||||
|
||||
*/
|
||||
enum nsCSSPropertyID {
|
||||
enum nsCSSPropertyID : int32_t {
|
||||
eCSSProperty_UNKNOWN = -1,
|
||||
|
||||
$property_ids
|
||||
|
|
|
@ -175,16 +175,18 @@ nsresult nsDOMCSSAttributeDeclaration::SetSMILValue(
|
|||
nsresult nsDOMCSSAttributeDeclaration::SetSMILValue(
|
||||
const nsCSSPropertyID aPropID, const SVGAnimatedLength& aLength) {
|
||||
return SetSMILValueHelper([aPropID, &aLength](DeclarationBlock& aDecl) {
|
||||
MOZ_ASSERT(aDecl.IsMutable());
|
||||
return SVGElement::UpdateDeclarationBlockFromLength(
|
||||
aDecl, aPropID, aLength, SVGElement::ValToUse::Anim);
|
||||
*aDecl.Raw(), aPropID, aLength, SVGElement::ValToUse::Anim);
|
||||
});
|
||||
}
|
||||
|
||||
nsresult nsDOMCSSAttributeDeclaration::SetSMILValue(
|
||||
const nsCSSPropertyID /*aPropID*/, const SVGAnimatedPathSegList& aPath) {
|
||||
return SetSMILValueHelper([&aPath](DeclarationBlock& aDecl) {
|
||||
MOZ_ASSERT(aDecl.IsMutable());
|
||||
return SVGElement::UpdateDeclarationBlockFromPath(
|
||||
aDecl, aPath, SVGElement::ValToUse::Anim);
|
||||
*aDecl.Raw(), aPath, SVGElement::ValToUse::Anim);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -589,40 +589,18 @@ impl<'le> GeckoElement<'le> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn attrs(&self) -> Option<&structs::AttrArray_Impl> {
|
||||
unsafe { self.0.mAttrs.mImpl.mPtr.as_ref() }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn non_mapped_attrs(&self) -> &[structs::AttrArray_InternalAttr] {
|
||||
let attrs = match self.attrs() {
|
||||
Some(attrs) => attrs,
|
||||
None => return &[],
|
||||
};
|
||||
fn attrs(&self) -> &[structs::AttrArray_InternalAttr] {
|
||||
unsafe {
|
||||
attrs.mBuffer.as_slice(attrs.mAttrCount as usize)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn mapped_attrs(&self) -> &[structs::AttrArray_InternalAttr] {
|
||||
let attrs = match self.attrs() {
|
||||
Some(attrs) => attrs,
|
||||
None => return &[],
|
||||
};
|
||||
unsafe {
|
||||
let attrs = match attrs.mMappedAttrs.as_ref() {
|
||||
Some(attrs) => attrs,
|
||||
match self.0.mAttrs.mImpl.mPtr.as_ref() {
|
||||
Some(attrs) => attrs.mBuffer.as_slice(attrs.mAttrCount as usize),
|
||||
None => return &[],
|
||||
};
|
||||
|
||||
attrs.mBuffer.as_slice(attrs.mAttrCount as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn iter_attrs(&self) -> impl Iterator<Item = &structs::AttrArray_InternalAttr> {
|
||||
self.non_mapped_attrs().iter().chain(self.mapped_attrs().iter())
|
||||
self.attrs().iter()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -630,7 +608,7 @@ impl<'le> GeckoElement<'le> {
|
|||
if !self.has_part_attr() {
|
||||
return None;
|
||||
}
|
||||
snapshot_helpers::find_attr(self.non_mapped_attrs(), &atom!("part"))
|
||||
snapshot_helpers::find_attr(self.attrs(), &atom!("part"))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -646,7 +624,7 @@ impl<'le> GeckoElement<'le> {
|
|||
}
|
||||
}
|
||||
|
||||
snapshot_helpers::find_attr(self.non_mapped_attrs(), &atom!("class"))
|
||||
snapshot_helpers::find_attr(self.attrs(), &atom!("class"))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1054,7 +1032,7 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
let slot: &structs::HTMLSlotElement = unsafe { mem::transmute(self.0) };
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
let base: &RawGeckoElement = &slot._base._base._base._base;
|
||||
let base: &RawGeckoElement = &slot._base._base._base;
|
||||
assert_eq!(base as *const _, self.0 as *const _, "Bad cast");
|
||||
}
|
||||
|
||||
|
@ -1198,7 +1176,7 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
|
||||
#[inline]
|
||||
fn exports_any_part(&self) -> bool {
|
||||
snapshot_helpers::find_attr(self.non_mapped_attrs(), &atom!("exportparts")).is_some()
|
||||
snapshot_helpers::find_attr(self.attrs(), &atom!("exportparts")).is_some()
|
||||
}
|
||||
|
||||
// FIXME(emilio): we should probably just return a reference to the Atom.
|
||||
|
@ -1207,8 +1185,7 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
if !self.has_id() {
|
||||
return None;
|
||||
}
|
||||
|
||||
snapshot_helpers::get_id(self.non_mapped_attrs())
|
||||
snapshot_helpers::get_id(self.attrs())
|
||||
}
|
||||
|
||||
fn each_attr_name<F>(&self, mut callback: F)
|
||||
|
@ -1239,7 +1216,7 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
where
|
||||
F: FnMut(&AtomIdent),
|
||||
{
|
||||
snapshot_helpers::each_exported_part(self.non_mapped_attrs(), name, callback)
|
||||
snapshot_helpers::each_exported_part(self.attrs(), name, callback)
|
||||
}
|
||||
|
||||
fn each_part<F>(&self, callback: F)
|
||||
|
@ -1793,7 +1770,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
|||
fn assigned_slot(&self) -> Option<Self> {
|
||||
let slot = self.extended_slots()?._base.mAssignedSlot.mRawPtr;
|
||||
|
||||
unsafe { Some(GeckoElement(&slot.as_ref()?._base._base._base._base)) }
|
||||
unsafe { Some(GeckoElement(&slot.as_ref()?._base._base._base)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1865,9 +1842,6 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
|||
local_name: &LocalName,
|
||||
operation: &AttrSelectorOperation<&AttrValue>,
|
||||
) -> bool {
|
||||
if self.attrs().is_none() {
|
||||
return false;
|
||||
}
|
||||
snapshot_helpers::attr_matches(self.iter_attrs(), ns, local_name, operation)
|
||||
}
|
||||
|
||||
|
@ -2074,7 +2048,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
|||
return false;
|
||||
}
|
||||
|
||||
let element_id = match snapshot_helpers::get_id(self.non_mapped_attrs()) {
|
||||
let element_id = match snapshot_helpers::get_id(self.attrs()) {
|
||||
Some(id) => id,
|
||||
None => return false,
|
||||
};
|
||||
|
@ -2094,7 +2068,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
|||
|
||||
#[inline]
|
||||
fn imported_part(&self, name: &AtomIdent) -> Option<AtomIdent> {
|
||||
snapshot_helpers::imported_part(self.non_mapped_attrs(), name)
|
||||
snapshot_helpers::imported_part(self.attrs(), name)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
[attributes.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[First set attribute is returned with mapped attribute set first]
|
||||
bug: 1303629
|
||||
expected: FAIL
|
|
@ -2920,6 +2920,7 @@ var browserTests = [
|
|||
"abc<font face=\"monospace\" size=\"7\" color=\"#ff0000\"><span style=\"background-color:rgb(0, 221, 221)\">[d]</span></font>ef",
|
||||
"abc<font size=\"7\" color=\"#ff0000\" face=\"monospace\"><span style=\"background-color:rgb(0, 221, 221)\">[d]</span></font>ef",
|
||||
"abc<font size=\"7\" face=\"monospace\" color=\"#ff0000\"><span style=\"background-color:rgb(0, 221, 221)\">[d]</span></font>ef",
|
||||
"abc<font size=\"7\" color=\"#ff0000\" face=\"monospace\" style=\"background-color:rgb(0, 221, 221)\">[d]</font>ef",
|
||||
"abc<font color=\"#ff0000\" face=\"monospace\" size=\"7\" style=\"background-color:rgb(0, 221, 221)\">[d]</font>ef",
|
||||
"abc<font color=\"#ff0000\" size=\"7\" face=\"monospace\" style=\"background-color:rgb(0, 221, 221)\">[d]</font>ef",
|
||||
"abc<font face=\"monospace\" color=\"#ff0000\" size=\"7\" style=\"background-color:rgb(0, 221, 221)\">[d]</font>ef",
|
||||
|
|
Загрузка…
Ссылка в новой задаче