mirror of
https://github.com/classilla/tenfourfox.git
synced 2025-02-22 18:29:11 +00:00
#438: M1375599
This commit is contained in:
parent
b8ebae8398
commit
84bfb83b16
@ -451,6 +451,16 @@ protected:
|
||||
RemoveStatesSilently(aStates);
|
||||
NotifyStateChange(aStates);
|
||||
}
|
||||
virtual void ToggleStates(EventStates aStates, bool aNotify)
|
||||
{
|
||||
NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
|
||||
"Should only be removing ESM-managed states here");
|
||||
mState ^= aStates;
|
||||
if (aNotify) {
|
||||
NotifyStateChange(aStates);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void UpdateEditableState(bool aNotify) override;
|
||||
|
||||
|
@ -276,10 +276,13 @@ private:
|
||||
|
||||
#define DIRECTION_STATES (NS_EVENT_STATE_LTR | NS_EVENT_STATE_RTL)
|
||||
|
||||
#define DISABLED_STATES (NS_EVENT_STATE_DISABLED | NS_EVENT_STATE_ENABLED)
|
||||
|
||||
#define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS | \
|
||||
NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER | \
|
||||
NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
|
||||
NS_EVENT_STATE_FULL_SCREEN | NS_EVENT_STATE_FULL_SCREEN_ANCESTOR | \
|
||||
DISABLED_STATES | \
|
||||
NS_EVENT_STATE_UNRESOLVED)
|
||||
|
||||
#define INTRINSIC_STATES (~ESM_MANAGED_STATES)
|
||||
|
@ -113,9 +113,14 @@ HTMLButtonElement::UpdateBarredFromConstraintValidation()
|
||||
void
|
||||
HTMLButtonElement::FieldSetDisabledChanged(bool aNotify)
|
||||
{
|
||||
UpdateBarredFromConstraintValidation();
|
||||
|
||||
// FieldSetDisabledChanged *has* to be called *before*
|
||||
// UpdateBarredFromConstraintValidation, because the latter depends on our
|
||||
// disabled state.
|
||||
nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify);
|
||||
|
||||
UpdateBarredFromConstraintValidation();
|
||||
UpdateState(aNotify);
|
||||
}
|
||||
|
||||
// nsIDOMHTMLButtonElement
|
||||
@ -522,6 +527,12 @@ HTMLButtonElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
}
|
||||
|
||||
if (aName == nsGkAtoms::type || aName == nsGkAtoms::disabled) {
|
||||
if (aName == nsGkAtoms::disabled) {
|
||||
// This *has* to be called *before* validity state check because
|
||||
// UpdateBarredFromConstraintValidation depends on our disabled state.
|
||||
UpdateDisabledState(aNotify);
|
||||
}
|
||||
|
||||
UpdateBarredFromConstraintValidation();
|
||||
UpdateState(aNotify);
|
||||
}
|
||||
|
@ -85,17 +85,22 @@ nsresult
|
||||
HTMLFieldSetElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue, bool aNotify)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled &&
|
||||
nsINode::GetFirstChild()) {
|
||||
if (!mElements) {
|
||||
mElements = new nsContentList(this, MatchListedElements, nullptr, nullptr,
|
||||
true);
|
||||
}
|
||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled) {
|
||||
// This *has* to be called *before* calling FieldSetDisabledChanged on our
|
||||
// controls, as they may depend on our disabled state.
|
||||
UpdateDisabledState(aNotify);
|
||||
|
||||
uint32_t length = mElements->Length(true);
|
||||
for (uint32_t i=0; i<length; ++i) {
|
||||
static_cast<nsGenericHTMLFormElement*>(mElements->Item(i))
|
||||
->FieldSetDisabledChanged(aNotify);
|
||||
if (nsINode::GetFirstChild()) {
|
||||
if (!mElements) {
|
||||
mElements = new nsContentList(this, MatchListedElements, nullptr, nullptr,
|
||||
true);
|
||||
}
|
||||
|
||||
uint32_t length = mElements->Length(true);
|
||||
for (uint32_t i=0; i<length; ++i) {
|
||||
static_cast<nsGenericHTMLFormElement*>(mElements->Item(i))
|
||||
->FieldSetDisabledChanged(aNotify);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1142,6 +1142,13 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
|
||||
if (aName == nsGkAtoms::required || aName == nsGkAtoms::disabled ||
|
||||
aName == nsGkAtoms::readonly) {
|
||||
if (aName == nsGkAtoms::disabled) {
|
||||
// This *has* to be called *before* validity state check because
|
||||
// UpdateBarredFromConstraintValidation and
|
||||
// UpdateValueMissingValidityState depend on our disabled state.
|
||||
UpdateDisabledState(aNotify);
|
||||
}
|
||||
|
||||
UpdateValueMissingValidityState();
|
||||
|
||||
// This *has* to be called *after* validity has changed.
|
||||
@ -7192,10 +7199,14 @@ HTMLInputElement::HasCachedSelection()
|
||||
void
|
||||
HTMLInputElement::FieldSetDisabledChanged(bool aNotify)
|
||||
{
|
||||
// This *has* to be called *before* UpdateBarredFromConstraintValidation and
|
||||
// UpdateValueMissingValidityState because these two functions depend on our
|
||||
// disabled state.
|
||||
nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify);
|
||||
|
||||
UpdateValueMissingValidityState();
|
||||
UpdateBarredFromConstraintValidation();
|
||||
|
||||
nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify);
|
||||
UpdateState(aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -64,8 +64,6 @@ public:
|
||||
NS_IMETHOD Reset() override;
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) override;
|
||||
|
||||
virtual bool IsDisabled() const override { return false; }
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult PostHandleEvent(
|
||||
EventChainPostVisitor& aVisitor) override;
|
||||
|
@ -105,13 +105,27 @@ HTMLOptGroupElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue, bool aNotify)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled) {
|
||||
// All our children <option> have their :disabled state depending on our
|
||||
// disabled attribute. We should make sure their state is updated.
|
||||
for (nsIContent* child = nsINode::GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
if (child->IsHTMLElement(nsGkAtoms::option)) {
|
||||
// No need to call |IsElement()| because it's an HTML element.
|
||||
child->AsElement()->UpdateState(true);
|
||||
|
||||
EventStates disabledStates;
|
||||
if (aValue) {
|
||||
disabledStates |= NS_EVENT_STATE_DISABLED;
|
||||
} else {
|
||||
disabledStates |= NS_EVENT_STATE_ENABLED;
|
||||
}
|
||||
|
||||
EventStates oldDisabledStates = State() & DISABLED_STATES;
|
||||
EventStates changedStates = disabledStates ^ oldDisabledStates;
|
||||
|
||||
if (!changedStates.IsEmpty()) {
|
||||
ToggleStates(changedStates, aNotify);
|
||||
|
||||
// All our children <option> have their :disabled state depending on our
|
||||
// disabled attribute. We should make sure their state is updated.
|
||||
for (nsIContent* child = nsINode::GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
if (auto optElement = HTMLOptionElement::FromContent(child)) {
|
||||
optElement->OptGroupDisabledChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,22 +134,6 @@ HTMLOptGroupElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
aNotify);
|
||||
}
|
||||
|
||||
EventStates
|
||||
HTMLOptGroupElement::IntrinsicState() const
|
||||
{
|
||||
EventStates state = nsGenericHTMLElement::IntrinsicState();
|
||||
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
|
||||
state |= NS_EVENT_STATE_DISABLED;
|
||||
state &= ~NS_EVENT_STATE_ENABLED;
|
||||
} else {
|
||||
state &= ~NS_EVENT_STATE_DISABLED;
|
||||
state |= NS_EVENT_STATE_ENABLED;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
HTMLOptGroupElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
|
@ -37,8 +37,6 @@ public:
|
||||
// nsIContent
|
||||
virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
|
||||
|
||||
virtual EventStates IntrinsicState() const override;
|
||||
|
||||
virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
|
||||
|
||||
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
@ -47,7 +45,7 @@ public:
|
||||
virtual nsIDOMNode* AsDOMNode() override { return this; }
|
||||
|
||||
virtual bool IsDisabled() const override {
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
|
||||
return State().HasState(NS_EVENT_STATE_DISABLED);
|
||||
}
|
||||
|
||||
bool Disabled() const
|
||||
|
@ -84,6 +84,39 @@ HTMLOptionElement::SetSelectedInternal(bool aValue, bool aNotify)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HTMLOptionElement::OptGroupDisabledChanged(bool aNotify)
|
||||
{
|
||||
UpdateDisabledState(aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLOptionElement::UpdateDisabledState(bool aNotify)
|
||||
{
|
||||
bool isDisabled = HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
|
||||
|
||||
if (!isDisabled) {
|
||||
nsIContent* parent = GetParent();
|
||||
if (auto optGroupElement = HTMLOptGroupElement::FromContentOrNull(parent)) {
|
||||
isDisabled = optGroupElement->IsDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
EventStates disabledStates;
|
||||
if (isDisabled) {
|
||||
disabledStates |= NS_EVENT_STATE_DISABLED;
|
||||
} else {
|
||||
disabledStates |= NS_EVENT_STATE_ENABLED;
|
||||
}
|
||||
|
||||
EventStates oldDisabledStates = State() & DISABLED_STATES;
|
||||
EventStates changedStates = disabledStates ^ oldDisabledStates;
|
||||
|
||||
if (!changedStates.IsEmpty()) {
|
||||
ToggleStates(changedStates, aNotify);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLOptionElement::GetSelected(bool* aValue)
|
||||
{
|
||||
@ -247,14 +280,19 @@ nsresult
|
||||
HTMLOptionElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue, bool aNotify)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
aName == nsGkAtoms::value && Selected()) {
|
||||
// Since this option is selected, changing value
|
||||
// may have changed missing validity state of the
|
||||
// Select element
|
||||
HTMLSelectElement* select = GetSelect();
|
||||
if (select) {
|
||||
select->UpdateValueMissingValidityState();
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::disabled) {
|
||||
UpdateDisabledState(aNotify);
|
||||
}
|
||||
|
||||
if (aName == nsGkAtoms::value && Selected()) {
|
||||
// Since this option is selected, changing value
|
||||
// may have changed missing validity state of the
|
||||
// Select element
|
||||
HTMLSelectElement* select = GetSelect();
|
||||
if (select) {
|
||||
select->UpdateValueMissingValidityState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,7 +343,7 @@ HTMLOptionElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Our new parent might change :disabled/:enabled state.
|
||||
UpdateState(false);
|
||||
UpdateDisabledState(false);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -316,7 +354,7 @@ HTMLOptionElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
// Our previous parent could have been involved in :disabled/:enabled state.
|
||||
UpdateState(false);
|
||||
UpdateDisabledState(false);
|
||||
}
|
||||
|
||||
EventStates
|
||||
@ -330,23 +368,6 @@ HTMLOptionElement::IntrinsicState() const
|
||||
state |= NS_EVENT_STATE_DEFAULT;
|
||||
}
|
||||
|
||||
// An <option> is disabled if it has @disabled set or if it's <optgroup> has
|
||||
// @disabled set.
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
|
||||
state |= NS_EVENT_STATE_DISABLED;
|
||||
state &= ~NS_EVENT_STATE_ENABLED;
|
||||
} else {
|
||||
nsIContent* parent = GetParent();
|
||||
if (parent && parent->IsHTMLElement(nsGkAtoms::optgroup) &&
|
||||
parent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
|
||||
state |= NS_EVENT_STATE_DISABLED;
|
||||
state &= ~NS_EVENT_STATE_ENABLED;
|
||||
} else {
|
||||
state &= ~NS_EVENT_STATE_DISABLED;
|
||||
state |= NS_EVENT_STATE_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,19 @@ public:
|
||||
|
||||
void SetSelectedInternal(bool aValue, bool aNotify);
|
||||
|
||||
/**
|
||||
* This callback is called by an optgroup on all its option elements whenever
|
||||
* its disabled state is changed so that option elements can know their
|
||||
* disabled state might have changed.
|
||||
*/
|
||||
void OptGroupDisabledChanged(bool aNotify);
|
||||
|
||||
/**
|
||||
* Check our disabled content attribute and optgroup's (if it exists) disabled
|
||||
* state to decide whether our disabled flag should be toggled.
|
||||
*/
|
||||
void UpdateDisabledState(bool aNotify);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers) override;
|
||||
@ -68,7 +81,7 @@ public:
|
||||
nsresult CopyInnerTo(mozilla::dom::Element* aDest);
|
||||
|
||||
virtual bool IsDisabled() const override {
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
|
||||
return State().HasState(NS_EVENT_STATE_DISABLED);
|
||||
}
|
||||
|
||||
bool Disabled() const
|
||||
|
@ -1293,6 +1293,12 @@ HTMLSelectElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::disabled) {
|
||||
// This *has* to be called *before* validity state check because
|
||||
// UpdateBarredFromConstraintValidation and
|
||||
// UpdateValueMissingValidityState depend on our disabled state.
|
||||
UpdateDisabledState(aNotify);
|
||||
|
||||
UpdateValueMissingValidityState();
|
||||
UpdateBarredFromConstraintValidation();
|
||||
} else if (aName == nsGkAtoms::required) {
|
||||
UpdateValueMissingValidityState();
|
||||
@ -1856,9 +1862,14 @@ HTMLSelectElement::UpdateBarredFromConstraintValidation()
|
||||
void
|
||||
HTMLSelectElement::FieldSetDisabledChanged(bool aNotify)
|
||||
{
|
||||
UpdateBarredFromConstraintValidation();
|
||||
|
||||
// This *has* to be called before UpdateBarredFromConstraintValidation and
|
||||
// UpdateValueMissingValidityState because these two functions depend on our
|
||||
// disabled state.
|
||||
nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify);
|
||||
|
||||
UpdateValueMissingValidityState();
|
||||
UpdateBarredFromConstraintValidation();
|
||||
UpdateState(aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1279,6 +1279,13 @@ HTMLTextAreaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::required || aName == nsGkAtoms::disabled ||
|
||||
aName == nsGkAtoms::readonly) {
|
||||
if (aName == nsGkAtoms::disabled) {
|
||||
// This *has* to be called *before* validity state check because
|
||||
// UpdateBarredFromConstraintValidation and
|
||||
// UpdateValueMissingValidityState depend on our disabled state.
|
||||
UpdateDisabledState(aNotify);
|
||||
}
|
||||
|
||||
UpdateValueMissingValidityState();
|
||||
|
||||
// This *has* to be called *after* validity has changed.
|
||||
@ -1542,10 +1549,14 @@ HTMLTextAreaElement::HasCachedSelection()
|
||||
void
|
||||
HTMLTextAreaElement::FieldSetDisabledChanged(bool aNotify)
|
||||
{
|
||||
// This *has* to be called before UpdateBarredFromConstraintValidation and
|
||||
// UpdateValueMissingValidityState because these two functions depend on our
|
||||
// disabled state.
|
||||
nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify);
|
||||
|
||||
UpdateValueMissingValidityState();
|
||||
UpdateBarredFromConstraintValidation();
|
||||
|
||||
nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify);
|
||||
UpdateState(aNotify);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
@ -2308,8 +2308,7 @@ nsGenericHTMLFormElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
bool
|
||||
nsGenericHTMLFormElement::IsDisabled() const
|
||||
{
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled) ||
|
||||
(mFieldSet && mFieldSet->IsDisabled());
|
||||
return State().HasState(NS_EVENT_STATE_DISABLED);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2355,17 +2354,6 @@ nsGenericHTMLFormElement::IntrinsicState() const
|
||||
// implement IntrinsicState() and are affected by that attribute.
|
||||
EventStates state = nsGenericHTMLElement::IntrinsicState();
|
||||
|
||||
if (CanBeDisabled()) {
|
||||
// :enabled/:disabled
|
||||
if (IsDisabled()) {
|
||||
state |= NS_EVENT_STATE_DISABLED;
|
||||
state &= ~NS_EVENT_STATE_ENABLED;
|
||||
} else {
|
||||
state &= ~NS_EVENT_STATE_DISABLED;
|
||||
state |= NS_EVENT_STATE_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
if (mForm && mForm->IsDefaultSubmitElement(this)) {
|
||||
NS_ASSERTION(IsSubmitControl(),
|
||||
"Default submit element that isn't a submit control.");
|
||||
@ -2625,10 +2613,37 @@ nsGenericHTMLFormElement::UpdateFieldSet(bool aNotify)
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLFormElement::UpdateDisabledState(bool aNotify)
|
||||
{
|
||||
if (!CanBeDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isDisabled = HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
|
||||
|
||||
if (!isDisabled && mFieldSet) {
|
||||
isDisabled = mFieldSet->IsDisabled();
|
||||
}
|
||||
|
||||
EventStates disabledStates;
|
||||
if (isDisabled) {
|
||||
disabledStates |= NS_EVENT_STATE_DISABLED;
|
||||
} else {
|
||||
disabledStates |= NS_EVENT_STATE_ENABLED;
|
||||
}
|
||||
|
||||
EventStates oldDisabledStates = State() & DISABLED_STATES;
|
||||
EventStates changedStates = disabledStates ^ oldDisabledStates;
|
||||
|
||||
if (!changedStates.IsEmpty()) {
|
||||
ToggleStates(changedStates, aNotify);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFormElement::FieldSetDisabledChanged(bool aNotify)
|
||||
{
|
||||
UpdateState(aNotify);
|
||||
UpdateDisabledState(aNotify);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1345,6 +1345,12 @@ public:
|
||||
*/
|
||||
virtual void FieldSetDisabledChanged(bool aNotify);
|
||||
|
||||
/**
|
||||
* Check our disabled content attribute and fieldset's (if it exists) disabled
|
||||
* state to decide whether our disabled flag should be toggled.
|
||||
*/
|
||||
void UpdateDisabledState(bool aNotify);
|
||||
|
||||
void FieldSetFirstLegendChanged(bool aNotify) {
|
||||
UpdateFieldSet(aNotify);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user