mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 09:18:42 +09:00
Bug 1363481 - Add the old attribute value as a parameter to Element::AfterSetAttr
Tag #1375
This commit is contained in:
parent
658bd351a0
commit
1f233fa14b
65 changed files with 352 additions and 161 deletions
|
|
@ -2382,7 +2382,8 @@ Element::MaybeCheckSameAttrVal(int32_t aNamespaceID,
|
|||
bool aNotify,
|
||||
nsAttrValue& aOldValue,
|
||||
uint8_t* aModType,
|
||||
bool* aHasListeners)
|
||||
bool* aHasListeners,
|
||||
bool* aOldValueSet)
|
||||
{
|
||||
bool modification = false;
|
||||
*aHasListeners = aNotify &&
|
||||
|
|
@ -2390,6 +2391,8 @@ Element::MaybeCheckSameAttrVal(int32_t aNamespaceID,
|
|||
NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
|
||||
this);
|
||||
|
||||
*aOldValueSet = false;
|
||||
|
||||
// If we have no listeners and aNotify is false, we are almost certainly
|
||||
// coming from the content sink and will almost certainly have no previous
|
||||
// value. Even if we do, setting the value is cheap when we have no
|
||||
|
|
@ -2413,6 +2416,7 @@ Element::MaybeCheckSameAttrVal(int32_t aNamespaceID,
|
|||
// We have to serialize the value anyway in order to create the
|
||||
// mutation event so there's no cost in doing it now.
|
||||
aOldValue.SetToSerialized(*info.mValue);
|
||||
*aOldValueSet = true;
|
||||
}
|
||||
bool valueMatches = aValue.EqualsAsStrings(*info.mValue);
|
||||
if (valueMatches && aPrefix == info.mName->GetPrefix()) {
|
||||
|
|
@ -2432,10 +2436,12 @@ Element::OnlyNotifySameValueSet(int32_t aNamespaceID, nsIAtom* aName,
|
|||
nsIAtom* aPrefix,
|
||||
const nsAttrValueOrString& aValue,
|
||||
bool aNotify, nsAttrValue& aOldValue,
|
||||
uint8_t* aModType, bool* aHasListeners)
|
||||
uint8_t* aModType, bool* aHasListeners,
|
||||
bool* aOldValueSet)
|
||||
{
|
||||
if (!MaybeCheckSameAttrVal(aNamespaceID, aName, aPrefix, aValue, aNotify,
|
||||
aOldValue, aModType, aHasListeners)) {
|
||||
aOldValue, aModType, aHasListeners,
|
||||
aOldValueSet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2466,9 +2472,10 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
|||
// OnlyNotifySameValueSet call.
|
||||
nsAttrValueOrString value(aValue);
|
||||
nsAttrValue oldValue;
|
||||
bool oldValueSet;
|
||||
|
||||
if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify,
|
||||
oldValue, &modType, &hasListeners)) {
|
||||
oldValue, &modType, &hasListeners, &oldValueSet)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2501,7 +2508,8 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
|||
attrValue.SetTo(aValue);
|
||||
}
|
||||
|
||||
return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
|
||||
return SetAttrAndNotify(aNamespaceID, aName, aPrefix,
|
||||
oldValueSet ? &oldValue : nullptr,
|
||||
attrValue, modType, hasListeners, aNotify,
|
||||
kCallAfterSetAttr, document, updateBatch);
|
||||
}
|
||||
|
|
@ -2526,9 +2534,10 @@ Element::SetParsedAttr(int32_t aNamespaceID, nsIAtom* aName,
|
|||
bool hasListeners;
|
||||
nsAttrValueOrString value(aParsedValue);
|
||||
nsAttrValue oldValue;
|
||||
bool oldValueSet;
|
||||
|
||||
if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify,
|
||||
oldValue, &modType, &hasListeners)) {
|
||||
oldValue, &modType, &hasListeners, &oldValueSet)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2542,7 +2551,8 @@ Element::SetParsedAttr(int32_t aNamespaceID, nsIAtom* aName,
|
|||
|
||||
nsIDocument* document = GetComposedDoc();
|
||||
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
|
||||
return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
|
||||
return SetAttrAndNotify(aNamespaceID, aName, aPrefix,
|
||||
oldValueSet ? &oldValue : nullptr,
|
||||
aParsedValue, modType, hasListeners, aNotify,
|
||||
kCallAfterSetAttr, document, updateBatch);
|
||||
}
|
||||
|
|
@ -2551,7 +2561,7 @@ nsresult
|
|||
Element::SetAttrAndNotify(int32_t aNamespaceID,
|
||||
nsIAtom* aName,
|
||||
nsIAtom* aPrefix,
|
||||
const nsAttrValue& aOldValue,
|
||||
const nsAttrValue* aOldValue,
|
||||
nsAttrValue& aParsedValue,
|
||||
uint8_t aModType,
|
||||
bool aFireMutation,
|
||||
|
|
@ -2573,6 +2583,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
|
||||
bool hadValidDir = false;
|
||||
bool hadDirAuto = false;
|
||||
bool oldValueSet;
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::dir) {
|
||||
|
|
@ -2583,8 +2594,8 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
// XXXbz Perhaps we should push up the attribute mapping function
|
||||
// stuff to Element?
|
||||
if (!IsAttributeMapped(aName) ||
|
||||
!SetMappedAttribute(aComposedDocument, aName, aParsedValue, &rv)) {
|
||||
rv = mAttrsAndChildren.SetAndSwapAttr(aName, aParsedValue);
|
||||
!SetAndSwapMappedAttribute(aComposedDocument, aName, aParsedValue, &oldValueSet, &rv)) {
|
||||
rv = mAttrsAndChildren.SetAndSwapAttr(aName, aParsedValue, &oldValueSet);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -2593,14 +2604,24 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
aNamespaceID,
|
||||
nsIDOMNode::ATTRIBUTE_NODE);
|
||||
|
||||
rv = mAttrsAndChildren.SetAndSwapAttr(ni, aParsedValue);
|
||||
rv = mAttrsAndChildren.SetAndSwapAttr(ni, aParsedValue, &oldValueSet);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If the old value owns its own data, we know it is OK to keep using it.
|
||||
const nsAttrValue* oldValue =
|
||||
aParsedValue.StoresOwnData() ? &aParsedValue : &aOldValue;
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// oldValue will be null if there was no previously set value
|
||||
const nsAttrValue* oldValue;
|
||||
if (aParsedValue.StoresOwnData()) {
|
||||
if (oldValueSet) {
|
||||
oldValue = &aParsedValue;
|
||||
} else {
|
||||
oldValue = nullptr;
|
||||
}
|
||||
} else {
|
||||
// No need to conditionally assign null here. If there was no previously
|
||||
// set value for the attribute, aOldValue will already be null.
|
||||
oldValue = aOldValue;
|
||||
}
|
||||
|
||||
if (aComposedDocument || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
|
||||
RefPtr<nsXBLBinding> binding = GetXBLBinding();
|
||||
|
|
@ -2618,7 +2639,14 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
MOZ_ASSERT(data->mState == CustomElementData::State::eCustom,
|
||||
"AttributeChanged callback should fire only if "
|
||||
"custom element state is custom");
|
||||
nsCOMPtr<nsIAtom> oldValueAtom = oldValue->GetAsAtom();
|
||||
nsCOMPtr<nsIAtom> oldValueAtom;
|
||||
if (oldValue) {
|
||||
oldValueAtom = oldValue->GetAsAtom();
|
||||
} else {
|
||||
// If there is no old value, get the value of the uninitialized attribute
|
||||
// that was swapped with aParsedValue.
|
||||
oldValueAtom = aParsedValue.GetAsAtom();
|
||||
}
|
||||
nsCOMPtr<nsIAtom> newValueAtom = valueForAfterSetAttr.GetAsAtom();
|
||||
nsAutoString ns;
|
||||
nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNamespaceID, ns);
|
||||
|
|
@ -2638,7 +2666,8 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
}
|
||||
|
||||
if (aCallAfterSetAttr) {
|
||||
rv = AfterSetAttr(aNamespaceID, aName, &valueForAfterSetAttr, aNotify);
|
||||
rv = AfterSetAttr(aNamespaceID, aName, &valueForAfterSetAttr, oldValue,
|
||||
aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) {
|
||||
|
|
@ -2654,7 +2683,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
// Callers only compute aOldValue under certain conditions which may not
|
||||
// be triggered by all nsIMutationObservers.
|
||||
nsNodeUtils::AttributeChanged(this, aNamespaceID, aName, aModType,
|
||||
oldValue == &aParsedValue ? &aParsedValue : nullptr);
|
||||
aParsedValue.StoresOwnData() ? &aParsedValue : nullptr);
|
||||
}
|
||||
|
||||
if (aFireMutation) {
|
||||
|
|
@ -2672,7 +2701,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
if (!newValue.IsEmpty()) {
|
||||
mutation.mNewAttrValue = NS_Atomize(newValue);
|
||||
}
|
||||
if (!oldValue->IsEmptyString()) {
|
||||
if (oldValue && !oldValue->IsEmptyString()) {
|
||||
mutation.mPrevAttrValue = oldValue->GetAsAtom();
|
||||
}
|
||||
mutation.mAttrChange = aModType;
|
||||
|
|
@ -2715,10 +2744,11 @@ Element::ParseAttribute(int32_t aNamespaceID,
|
|||
}
|
||||
|
||||
bool
|
||||
Element::SetMappedAttribute(nsIDocument* aDocument,
|
||||
nsIAtom* aName,
|
||||
nsAttrValue& aValue,
|
||||
nsresult* aRetval)
|
||||
Element::SetAndSwapMappedAttribute(nsIDocument* aDocument,
|
||||
nsIAtom* aName,
|
||||
nsAttrValue& aValue,
|
||||
bool* aValueWasSet,
|
||||
nsresult* aRetval)
|
||||
{
|
||||
*aRetval = NS_OK;
|
||||
return false;
|
||||
|
|
@ -2886,7 +2916,7 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
}
|
||||
}
|
||||
|
||||
rv = AfterSetAttr(aNameSpaceID, aName, nullptr, aNotify);
|
||||
rv = AfterSetAttr(aNameSpaceID, aName, nullptr, &oldValue, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateState(aNotify);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue