2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2010-07-14 10:39:48 +04:00
|
|
|
|
2013-02-18 16:24:58 +04:00
|
|
|
#include "mozilla/dom/HTMLOptionElement.h"
|
2013-02-18 16:26:57 +04:00
|
|
|
#include "mozilla/dom/HTMLOptionElementBinding.h"
|
2013-04-04 11:03:33 +04:00
|
|
|
#include "mozilla/dom/HTMLSelectElement.h"
|
2007-01-30 03:06:41 +03:00
|
|
|
#include "nsGkAtoms.h"
|
1998-09-02 04:56:01 +04:00
|
|
|
#include "nsStyleConsts.h"
|
1998-09-23 21:16:51 +04:00
|
|
|
#include "nsIFormControl.h"
|
|
|
|
#include "nsIForm.h"
|
2002-01-26 02:35:44 +03:00
|
|
|
#include "nsISelectControlFrame.h"
|
1998-09-02 04:56:01 +04:00
|
|
|
|
1999-01-30 04:02:28 +03:00
|
|
|
// Notify/query select frame for selected state
|
|
|
|
#include "nsIFormControlFrame.h"
|
2019-01-02 16:05:23 +03:00
|
|
|
#include "mozilla/dom/Document.h"
|
2000-05-10 17:13:39 +04:00
|
|
|
#include "nsNodeInfoManager.h"
|
2000-02-12 19:24:19 +03:00
|
|
|
#include "nsCOMPtr.h"
|
2014-04-03 08:18:36 +04:00
|
|
|
#include "mozilla/EventStates.h"
|
2006-07-19 08:36:36 +04:00
|
|
|
#include "nsContentCreatorFunctions.h"
|
2008-04-11 21:29:06 +04:00
|
|
|
#include "mozAutoDocUpdate.h"
|
2013-04-04 16:01:08 +04:00
|
|
|
#include "nsTextNode.h"
|
1999-01-30 04:02:28 +03:00
|
|
|
|
2010-07-14 17:45:11 +04:00
|
|
|
/**
|
|
|
|
* Implementation of <option>
|
|
|
|
*/
|
|
|
|
|
2013-06-19 18:24:37 +04:00
|
|
|
NS_IMPL_NS_NEW_HTML_ELEMENT(Option)
|
1998-09-02 04:56:01 +04:00
|
|
|
|
2013-02-18 16:24:58 +04:00
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
2018-09-21 23:45:49 +03:00
|
|
|
HTMLOptionElement::HTMLOptionElement(
|
|
|
|
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
|
|
|
: nsGenericHTMLElement(std::move(aNodeInfo)),
|
2011-10-17 18:59:28 +04:00
|
|
|
mSelectedChanged(false),
|
|
|
|
mIsSelected(false),
|
|
|
|
mIsInSetDefaultSelected(false) {
|
2011-06-01 05:46:57 +04:00
|
|
|
// We start off enabled
|
|
|
|
AddStatesSilently(NS_EVENT_STATE_ENABLED);
|
1998-09-02 04:56:01 +04:00
|
|
|
}
|
|
|
|
|
2013-02-18 16:24:58 +04:00
|
|
|
HTMLOptionElement::~HTMLOptionElement() {}
|
1998-09-02 04:56:01 +04:00
|
|
|
|
2013-02-18 16:24:58 +04:00
|
|
|
NS_IMPL_ELEMENT_CLONE(HTMLOptionElement)
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2013-06-19 18:24:37 +04:00
|
|
|
mozilla::dom::HTMLFormElement* HTMLOptionElement::GetForm() {
|
2013-04-04 11:03:33 +04:00
|
|
|
HTMLSelectElement* selectControl = GetSelect();
|
2013-02-18 16:26:57 +04:00
|
|
|
return selectControl ? selectControl->GetForm() : nullptr;
|
1998-09-02 04:56:01 +04:00
|
|
|
}
|
|
|
|
|
2013-02-18 16:24:58 +04:00
|
|
|
void HTMLOptionElement::SetSelectedInternal(bool aValue, bool aNotify) {
|
2011-10-17 18:59:28 +04:00
|
|
|
mSelectedChanged = true;
|
2002-03-07 06:34:29 +03:00
|
|
|
mIsSelected = aValue;
|
2001-11-05 09:15:14 +03:00
|
|
|
|
2011-06-01 05:46:57 +04:00
|
|
|
// When mIsInSetDefaultSelected is true, the state change will be handled by
|
2007-12-04 19:50:32 +03:00
|
|
|
// SetAttr/UnsetAttr.
|
2011-06-01 05:46:57 +04:00
|
|
|
if (!mIsInSetDefaultSelected) {
|
|
|
|
UpdateState(aNotify);
|
2004-01-21 07:28:57 +03:00
|
|
|
}
|
2001-11-02 10:40:01 +03:00
|
|
|
}
|
2000-12-23 13:56:31 +03:00
|
|
|
|
Bug 1375599 - Change IsDisabled() to look at NS_EVENT_STATE_DISABLED instead of the "disabled" attribute. r=bz
In order to speed up IsDisabled(), instead of querying for the @disabled
attribute, we're now using the NS_EVENT_STATE_DISABLED flag to know whether an
element is disabled.
It is safe to use the NS_EVENT_STATE_DISABLED flag for the following reasons:
- For form elements, nsGenericHTMLFormElement::IsDisabled() is only called on
form elements that can be disabled; form elements that can't be disabled
overrides IsDisabled() to return false directly.
And, before this patch, NS_EVENT_STATE_DISABLED flag is set by
nsGenericHTMLFormElement::IntrinsicState() if and only if IsDisabled() in all
cases when CanBeDisabled() is true, and when CanBeDisabled() is false then
IsDisabled() is always false and the flag is not set.
- For non form elements, optgroup and option have the flag matching
IsDisabled(). Note that option's IsDisabled() should also refer to optgroup's
(if it exists) disabled state, which was not done before this patch.
For this to work correctly, we need to set NS_EVENT_STATE_DISABLED earlier,
that is, in AfterSetAttr(), before any consumer of IsDisabled().
We also need to update the flag whenever the element's parent (e.g. fieldset or
optgroup) disabled state changes and when moving into/out of a parent
container.
Note that NS_EVENT_STATE_DISABLED/ENABLED is now part of the
EXTERNALLY_MANAGED_STATES.
MozReview-Commit-ID: KSceikeqvvU
2017-07-20 09:15:00 +03:00
|
|
|
void HTMLOptionElement::OptGroupDisabledChanged(bool aNotify) {
|
|
|
|
UpdateDisabledState(aNotify);
|
|
|
|
}
|
|
|
|
|
|
|
|
void HTMLOptionElement::UpdateDisabledState(bool aNotify) {
|
|
|
|
bool isDisabled = HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
|
|
|
|
|
|
|
|
if (!isDisabled) {
|
|
|
|
nsIContent* parent = GetParent();
|
2018-03-22 00:39:04 +03:00
|
|
|
if (auto optGroupElement = HTMLOptGroupElement::FromNodeOrNull(parent)) {
|
Bug 1375599 - Change IsDisabled() to look at NS_EVENT_STATE_DISABLED instead of the "disabled" attribute. r=bz
In order to speed up IsDisabled(), instead of querying for the @disabled
attribute, we're now using the NS_EVENT_STATE_DISABLED flag to know whether an
element is disabled.
It is safe to use the NS_EVENT_STATE_DISABLED flag for the following reasons:
- For form elements, nsGenericHTMLFormElement::IsDisabled() is only called on
form elements that can be disabled; form elements that can't be disabled
overrides IsDisabled() to return false directly.
And, before this patch, NS_EVENT_STATE_DISABLED flag is set by
nsGenericHTMLFormElement::IntrinsicState() if and only if IsDisabled() in all
cases when CanBeDisabled() is true, and when CanBeDisabled() is false then
IsDisabled() is always false and the flag is not set.
- For non form elements, optgroup and option have the flag matching
IsDisabled(). Note that option's IsDisabled() should also refer to optgroup's
(if it exists) disabled state, which was not done before this patch.
For this to work correctly, we need to set NS_EVENT_STATE_DISABLED earlier,
that is, in AfterSetAttr(), before any consumer of IsDisabled().
We also need to update the flag whenever the element's parent (e.g. fieldset or
optgroup) disabled state changes and when moving into/out of a parent
container.
Note that NS_EVENT_STATE_DISABLED/ENABLED is now part of the
EXTERNALLY_MANAGED_STATES.
MozReview-Commit-ID: KSceikeqvvU
2017-07-20 09:15:00 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-18 16:24:58 +04:00
|
|
|
void HTMLOptionElement::SetSelected(bool aValue) {
|
2001-11-02 10:40:01 +03:00
|
|
|
// Note: The select content obj maintains all the PresState
|
|
|
|
// so defer to it to get the answer
|
2013-04-04 11:03:33 +04:00
|
|
|
HTMLSelectElement* selectInt = GetSelect();
|
2001-11-02 10:40:01 +03:00
|
|
|
if (selectInt) {
|
2013-08-14 10:57:04 +04:00
|
|
|
int32_t index = Index();
|
2013-09-28 23:04:20 +04:00
|
|
|
uint32_t mask = HTMLSelectElement::SET_DISABLED | HTMLSelectElement::NOTIFY;
|
|
|
|
if (aValue) {
|
|
|
|
mask |= HTMLSelectElement::IS_SELECTED;
|
|
|
|
}
|
|
|
|
|
2001-11-02 10:40:01 +03:00
|
|
|
// This should end up calling SetSelectedInternal
|
2013-09-28 23:04:20 +04:00
|
|
|
selectInt->SetOptionsSelectedByIndex(index, index, mask);
|
2000-09-05 17:37:16 +04:00
|
|
|
} else {
|
2011-10-17 18:59:28 +04:00
|
|
|
SetSelectedInternal(aValue, true);
|
1999-08-27 07:59:49 +04:00
|
|
|
}
|
2013-08-14 10:57:04 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int32_t HTMLOptionElement::Index() {
|
|
|
|
static int32_t defaultIndex = 0;
|
1999-04-09 03:47:49 +04:00
|
|
|
|
2012-02-25 00:30:54 +04:00
|
|
|
// Only select elements can contain a list of options.
|
2013-04-04 11:03:33 +04:00
|
|
|
HTMLSelectElement* selectElement = GetSelect();
|
2012-02-25 00:30:54 +04:00
|
|
|
if (!selectElement) {
|
2013-08-14 10:57:04 +04:00
|
|
|
return defaultIndex;
|
2012-02-25 00:30:54 +04:00
|
|
|
}
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2013-03-17 11:55:17 +04:00
|
|
|
HTMLOptionsCollection* options = selectElement->GetOptions();
|
2012-02-25 00:30:54 +04:00
|
|
|
if (!options) {
|
2013-08-14 10:57:04 +04:00
|
|
|
return defaultIndex;
|
1999-04-09 03:47:49 +04:00
|
|
|
}
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2013-08-14 10:57:04 +04:00
|
|
|
int32_t index = defaultIndex;
|
2016-03-28 20:28:15 +03:00
|
|
|
MOZ_ALWAYS_SUCCEEDS(options->GetOptionIndex(this, 0, true, &index));
|
2013-08-14 10:57:04 +04:00
|
|
|
return index;
|
1999-04-09 03:47:49 +04:00
|
|
|
}
|
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
nsChangeHint HTMLOptionElement::GetAttributeChangeHint(const nsAtom* aAttribute,
|
2013-02-18 16:24:58 +04:00
|
|
|
int32_t aModType) const {
|
2004-10-24 21:10:32 +04:00
|
|
|
nsChangeHint retval =
|
|
|
|
nsGenericHTMLElement::GetAttributeChangeHint(aAttribute, aModType);
|
1999-07-07 05:24:40 +04:00
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
if (aAttribute == nsGkAtoms::label || aAttribute == nsGkAtoms::text) {
|
2016-05-23 06:26:03 +03:00
|
|
|
retval |= NS_STYLE_HINT_REFLOW;
|
2003-07-12 01:16:12 +04:00
|
|
|
}
|
2004-10-24 21:10:32 +04:00
|
|
|
return retval;
|
1999-07-07 05:24:40 +04:00
|
|
|
}
|
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
nsresult HTMLOptionElement::BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
2017-03-16 21:50:41 +03:00
|
|
|
const nsAttrValueOrString* aValue,
|
2013-02-18 16:24:58 +04:00
|
|
|
bool aNotify) {
|
2007-12-04 19:50:32 +03:00
|
|
|
nsresult rv =
|
|
|
|
nsGenericHTMLElement::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (aNamespaceID != kNameSpaceID_None || aName != nsGkAtoms::selected ||
|
|
|
|
mSelectedChanged) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2013-02-18 16:24:58 +04:00
|
|
|
|
2007-12-04 19:50:32 +03:00
|
|
|
// We just changed out selected state (since we look at the "selected"
|
2011-04-12 16:32:00 +04:00
|
|
|
// attribute when mSelectedChanged is false). Let's tell our select about
|
2007-12-04 19:50:32 +03:00
|
|
|
// it.
|
2013-04-04 11:03:33 +04:00
|
|
|
HTMLSelectElement* selectInt = GetSelect();
|
2007-12-04 19:50:32 +03:00
|
|
|
if (!selectInt) {
|
2017-05-26 08:59:00 +03:00
|
|
|
// If option is a child of select, SetOptionsSelectedByIndex will set
|
|
|
|
// mIsSelected if needed.
|
|
|
|
mIsSelected = aValue;
|
2007-12-04 19:50:32 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ASSERTION(!mSelectedChanged, "Shouldn't be here");
|
2013-02-18 16:24:58 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool inSetDefaultSelected = mIsInSetDefaultSelected;
|
2011-10-17 18:59:28 +04:00
|
|
|
mIsInSetDefaultSelected = true;
|
2013-02-18 16:24:58 +04:00
|
|
|
|
2013-08-14 10:57:04 +04:00
|
|
|
int32_t index = Index();
|
2013-09-28 23:04:20 +04:00
|
|
|
uint32_t mask = HTMLSelectElement::SET_DISABLED;
|
2017-05-26 08:59:00 +03:00
|
|
|
if (aValue) {
|
2013-09-28 23:04:20 +04:00
|
|
|
mask |= HTMLSelectElement::IS_SELECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aNotify) {
|
|
|
|
mask |= HTMLSelectElement::NOTIFY;
|
|
|
|
}
|
|
|
|
|
2013-12-04 17:02:00 +04:00
|
|
|
// This can end up calling SetSelectedInternal if our selected state needs to
|
|
|
|
// change, which we will allow to take effect so that parts of
|
|
|
|
// SetOptionsSelectedByIndex that might depend on it working don't get
|
|
|
|
// confused.
|
2013-09-28 23:04:20 +04:00
|
|
|
selectInt->SetOptionsSelectedByIndex(index, index, mask);
|
2007-12-04 19:50:32 +03:00
|
|
|
|
|
|
|
// Now reset our members; when we finish the attr set we'll end up with the
|
|
|
|
// rigt selected state.
|
|
|
|
mIsInSetDefaultSelected = inSetDefaultSelected;
|
2013-12-04 17:02:00 +04:00
|
|
|
// mIsSelected might have been changed by SetOptionsSelectedByIndex. Possibly
|
2017-05-26 08:59:00 +03:00
|
|
|
// more than once; make sure our mSelectedChanged state is set back correctly.
|
|
|
|
mSelectedChanged = false;
|
2007-12-04 19:50:32 +03:00
|
|
|
|
2013-07-24 11:37:14 +04:00
|
|
|
return NS_OK;
|
2007-12-04 19:50:32 +03:00
|
|
|
}
|
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
nsresult HTMLOptionElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
2017-05-19 00:09:01 +03:00
|
|
|
const nsAttrValue* aValue,
|
2017-10-10 00:33:38 +03:00
|
|
|
const nsAttrValue* aOldValue,
|
|
|
|
nsIPrincipal* aSubjectPrincipal,
|
|
|
|
bool aNotify) {
|
Bug 1375599 - Change IsDisabled() to look at NS_EVENT_STATE_DISABLED instead of the "disabled" attribute. r=bz
In order to speed up IsDisabled(), instead of querying for the @disabled
attribute, we're now using the NS_EVENT_STATE_DISABLED flag to know whether an
element is disabled.
It is safe to use the NS_EVENT_STATE_DISABLED flag for the following reasons:
- For form elements, nsGenericHTMLFormElement::IsDisabled() is only called on
form elements that can be disabled; form elements that can't be disabled
overrides IsDisabled() to return false directly.
And, before this patch, NS_EVENT_STATE_DISABLED flag is set by
nsGenericHTMLFormElement::IntrinsicState() if and only if IsDisabled() in all
cases when CanBeDisabled() is true, and when CanBeDisabled() is false then
IsDisabled() is always false and the flag is not set.
- For non form elements, optgroup and option have the flag matching
IsDisabled(). Note that option's IsDisabled() should also refer to optgroup's
(if it exists) disabled state, which was not done before this patch.
For this to work correctly, we need to set NS_EVENT_STATE_DISABLED earlier,
that is, in AfterSetAttr(), before any consumer of IsDisabled().
We also need to update the flag whenever the element's parent (e.g. fieldset or
optgroup) disabled state changes and when moving into/out of a parent
container.
Note that NS_EVENT_STATE_DISABLED/ENABLED is now part of the
EXTERNALLY_MANAGED_STATES.
MozReview-Commit-ID: KSceikeqvvU
2017-07-20 09:15:00 +03:00
|
|
|
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();
|
|
|
|
}
|
2014-05-06 21:19:00 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsGenericHTMLElement::AfterSetAttr(
|
2017-10-10 00:33:38 +03:00
|
|
|
aNameSpaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
|
2014-05-06 21:19:00 +04:00
|
|
|
}
|
|
|
|
|
2013-02-18 16:24:58 +04:00
|
|
|
void HTMLOptionElement::GetText(nsAString& aText) {
|
2002-09-04 03:23:00 +04:00
|
|
|
nsAutoString text;
|
2012-10-21 11:38:40 +04:00
|
|
|
|
|
|
|
nsIContent* child = nsINode::GetFirstChild();
|
|
|
|
while (child) {
|
2018-03-29 01:01:47 +03:00
|
|
|
if (Text* textChild = child->GetAsText()) {
|
|
|
|
textChild->AppendTextTo(text);
|
2012-10-21 11:38:40 +04:00
|
|
|
}
|
2015-03-03 14:08:59 +03:00
|
|
|
if (child->IsHTMLElement(nsGkAtoms::script) ||
|
|
|
|
child->IsSVGElement(nsGkAtoms::script)) {
|
2012-10-21 11:38:40 +04:00
|
|
|
child = child->GetNextNonChildNode(this);
|
|
|
|
} else {
|
|
|
|
child = child->GetNextNode(this);
|
|
|
|
}
|
|
|
|
}
|
2000-02-12 19:24:19 +03:00
|
|
|
|
2002-09-26 12:21:26 +04:00
|
|
|
// XXX No CompressWhitespace for nsAString. Sad.
|
2011-10-17 18:59:28 +04:00
|
|
|
text.CompressWhitespace(true, true);
|
2002-09-26 12:21:26 +04:00
|
|
|
aText = text;
|
2000-01-15 04:42:56 +03:00
|
|
|
}
|
|
|
|
|
2017-11-09 04:43:09 +03:00
|
|
|
void HTMLOptionElement::SetText(const nsAString& aText, ErrorResult& aRv) {
|
|
|
|
aRv = nsContentUtils::SetNodeTextContent(this, aText, true);
|
2002-03-31 13:48:38 +04:00
|
|
|
}
|
|
|
|
|
2019-01-02 16:05:23 +03:00
|
|
|
nsresult HTMLOptionElement::BindToTree(Document* aDocument, nsIContent* aParent,
|
2018-07-31 21:18:38 +03:00
|
|
|
nsIContent* aBindingParent) {
|
2012-06-01 13:46:43 +04:00
|
|
|
nsresult rv =
|
|
|
|
nsGenericHTMLElement::BindToTree(aDocument, aParent, aBindingParent);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// Our new parent might change :disabled/:enabled state.
|
Bug 1375599 - Change IsDisabled() to look at NS_EVENT_STATE_DISABLED instead of the "disabled" attribute. r=bz
In order to speed up IsDisabled(), instead of querying for the @disabled
attribute, we're now using the NS_EVENT_STATE_DISABLED flag to know whether an
element is disabled.
It is safe to use the NS_EVENT_STATE_DISABLED flag for the following reasons:
- For form elements, nsGenericHTMLFormElement::IsDisabled() is only called on
form elements that can be disabled; form elements that can't be disabled
overrides IsDisabled() to return false directly.
And, before this patch, NS_EVENT_STATE_DISABLED flag is set by
nsGenericHTMLFormElement::IntrinsicState() if and only if IsDisabled() in all
cases when CanBeDisabled() is true, and when CanBeDisabled() is false then
IsDisabled() is always false and the flag is not set.
- For non form elements, optgroup and option have the flag matching
IsDisabled(). Note that option's IsDisabled() should also refer to optgroup's
(if it exists) disabled state, which was not done before this patch.
For this to work correctly, we need to set NS_EVENT_STATE_DISABLED earlier,
that is, in AfterSetAttr(), before any consumer of IsDisabled().
We also need to update the flag whenever the element's parent (e.g. fieldset or
optgroup) disabled state changes and when moving into/out of a parent
container.
Note that NS_EVENT_STATE_DISABLED/ENABLED is now part of the
EXTERNALLY_MANAGED_STATES.
MozReview-Commit-ID: KSceikeqvvU
2017-07-20 09:15:00 +03:00
|
|
|
UpdateDisabledState(false);
|
2012-06-01 13:46:43 +04:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-02-18 16:24:58 +04:00
|
|
|
void HTMLOptionElement::UnbindFromTree(bool aDeep, bool aNullParent) {
|
2012-06-01 13:46:43 +04:00
|
|
|
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
|
|
|
|
|
|
|
// Our previous parent could have been involved in :disabled/:enabled state.
|
Bug 1375599 - Change IsDisabled() to look at NS_EVENT_STATE_DISABLED instead of the "disabled" attribute. r=bz
In order to speed up IsDisabled(), instead of querying for the @disabled
attribute, we're now using the NS_EVENT_STATE_DISABLED flag to know whether an
element is disabled.
It is safe to use the NS_EVENT_STATE_DISABLED flag for the following reasons:
- For form elements, nsGenericHTMLFormElement::IsDisabled() is only called on
form elements that can be disabled; form elements that can't be disabled
overrides IsDisabled() to return false directly.
And, before this patch, NS_EVENT_STATE_DISABLED flag is set by
nsGenericHTMLFormElement::IntrinsicState() if and only if IsDisabled() in all
cases when CanBeDisabled() is true, and when CanBeDisabled() is false then
IsDisabled() is always false and the flag is not set.
- For non form elements, optgroup and option have the flag matching
IsDisabled(). Note that option's IsDisabled() should also refer to optgroup's
(if it exists) disabled state, which was not done before this patch.
For this to work correctly, we need to set NS_EVENT_STATE_DISABLED earlier,
that is, in AfterSetAttr(), before any consumer of IsDisabled().
We also need to update the flag whenever the element's parent (e.g. fieldset or
optgroup) disabled state changes and when moving into/out of a parent
container.
Note that NS_EVENT_STATE_DISABLED/ENABLED is now part of the
EXTERNALLY_MANAGED_STATES.
MozReview-Commit-ID: KSceikeqvvU
2017-07-20 09:15:00 +03:00
|
|
|
UpdateDisabledState(false);
|
2012-06-01 13:46:43 +04:00
|
|
|
}
|
|
|
|
|
2013-02-18 16:24:58 +04:00
|
|
|
EventStates HTMLOptionElement::IntrinsicState() const {
|
2014-04-03 08:18:36 +04:00
|
|
|
EventStates state = nsGenericHTMLElement::IntrinsicState();
|
2011-06-28 14:45:51 +04:00
|
|
|
if (Selected()) {
|
2005-06-03 06:02:45 +04:00
|
|
|
state |= NS_EVENT_STATE_CHECKED;
|
|
|
|
}
|
2011-06-28 14:45:51 +04:00
|
|
|
if (DefaultSelected()) {
|
2006-08-16 07:20:19 +04:00
|
|
|
state |= NS_EVENT_STATE_DEFAULT;
|
|
|
|
}
|
|
|
|
|
2005-06-03 06:02:45 +04:00
|
|
|
return state;
|
|
|
|
}
|
2002-03-31 13:48:38 +04:00
|
|
|
|
1999-04-09 03:47:49 +04:00
|
|
|
// Get the select content element that contains this option
|
2013-02-18 16:24:58 +04:00
|
|
|
HTMLSelectElement* HTMLOptionElement::GetSelect() {
|
2016-03-03 11:03:44 +03:00
|
|
|
nsIContent* parent = GetParent();
|
2016-03-03 11:47:36 +03:00
|
|
|
if (!parent) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-03-22 00:39:04 +03:00
|
|
|
HTMLSelectElement* select = HTMLSelectElement::FromNode(parent);
|
2016-03-03 11:03:44 +03:00
|
|
|
if (select) {
|
|
|
|
return select;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parent->IsHTMLElement(nsGkAtoms::optgroup)) {
|
|
|
|
return nullptr;
|
1999-05-05 00:53:26 +04:00
|
|
|
}
|
2013-02-18 16:24:58 +04:00
|
|
|
|
2018-03-22 00:39:04 +03:00
|
|
|
return HTMLSelectElement::FromNodeOrNull(parent->GetParent());
|
1999-05-05 00:53:26 +04:00
|
|
|
}
|
|
|
|
|
2013-01-22 14:53:13 +04:00
|
|
|
already_AddRefed<HTMLOptionElement> HTMLOptionElement::Option(
|
|
|
|
const GlobalObject& aGlobal, const nsAString& aText,
|
|
|
|
const Optional<nsAString>& aValue, bool aDefaultSelected, bool aSelected,
|
2017-05-18 12:56:27 +03:00
|
|
|
ErrorResult& aError) {
|
2016-01-30 20:05:36 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(aGlobal.GetAsSupports());
|
2019-01-02 16:05:23 +03:00
|
|
|
Document* doc;
|
2013-01-22 14:53:13 +04:00
|
|
|
if (!win || !(doc = win->GetExtantDoc())) {
|
|
|
|
aError.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
|
|
|
}
|
1999-05-05 00:53:26 +04:00
|
|
|
|
2018-09-21 23:45:49 +03:00
|
|
|
RefPtr<mozilla::dom::NodeInfo> nodeInfo = doc->NodeInfoManager()->GetNodeInfo(
|
2013-01-22 14:53:13 +04:00
|
|
|
nsGkAtoms::option, nullptr, kNameSpaceID_XHTML, ELEMENT_NODE);
|
|
|
|
|
2018-09-21 23:45:49 +03:00
|
|
|
RefPtr<HTMLOptionElement> option = new HTMLOptionElement(nodeInfo.forget());
|
2000-12-23 13:56:31 +03:00
|
|
|
|
2017-05-18 12:56:27 +03:00
|
|
|
if (!aText.IsEmpty()) {
|
2007-11-28 03:52:37 +03:00
|
|
|
// Create a new text node and append it to the option
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsTextNode> textContent =
|
2013-04-04 16:01:08 +04:00
|
|
|
new nsTextNode(option->NodeInfo()->NodeInfoManager());
|
2010-12-03 11:24:17 +03:00
|
|
|
|
2017-05-18 12:56:27 +03:00
|
|
|
textContent->SetText(aText, false);
|
2013-02-18 16:24:58 +04:00
|
|
|
|
2013-01-22 14:53:13 +04:00
|
|
|
aError = option->AppendChildTo(textContent, false);
|
|
|
|
if (aError.Failed()) {
|
|
|
|
return nullptr;
|
1999-03-02 06:26:29 +03:00
|
|
|
}
|
2017-05-18 12:56:27 +03:00
|
|
|
}
|
1999-03-02 06:26:29 +03:00
|
|
|
|
2017-05-18 12:56:27 +03:00
|
|
|
if (aValue.WasPassed()) {
|
|
|
|
// Set the value attribute for this element. We're calling SetAttr
|
|
|
|
// directly because we want to pass aNotify == false.
|
|
|
|
aError = option->SetAttr(kNameSpaceID_None, nsGkAtoms::value,
|
|
|
|
aValue.Value(), false);
|
|
|
|
if (aError.Failed()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aDefaultSelected) {
|
|
|
|
// We're calling SetAttr directly because we want to pass
|
|
|
|
// aNotify == false.
|
|
|
|
aError = option->SetAttr(kNameSpaceID_None, nsGkAtoms::selected,
|
|
|
|
EmptyString(), false);
|
|
|
|
if (aError.Failed()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-09 04:43:09 +03:00
|
|
|
option->SetSelected(aSelected);
|
2017-05-26 08:59:00 +03:00
|
|
|
option->SetSelectedChanged(false);
|
|
|
|
|
2013-01-22 14:53:13 +04:00
|
|
|
return option.forget();
|
1999-01-30 04:02:28 +03:00
|
|
|
}
|
2009-12-11 07:02:13 +03:00
|
|
|
|
2018-08-09 02:58:44 +03:00
|
|
|
nsresult HTMLOptionElement::CopyInnerTo(Element* aDest) {
|
|
|
|
nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest);
|
2009-12-11 07:02:13 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2011-10-18 14:53:36 +04:00
|
|
|
if (aDest->OwnerDoc()->IsStaticDocument()) {
|
2013-02-18 16:24:58 +04:00
|
|
|
static_cast<HTMLOptionElement*>(aDest)->SetSelected(Selected());
|
2009-12-11 07:02:13 +03:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
Bug 1117172 part 3. Change the wrappercached WrapObject methods to allow passing in aGivenProto. r=peterv
The only manual changes here are to BindingUtils.h, BindingUtils.cpp,
Codegen.py, Element.cpp, IDBFileRequest.cpp, IDBObjectStore.cpp,
dom/workers/Navigator.cpp, WorkerPrivate.cpp, DeviceStorageRequestChild.cpp,
Notification.cpp, nsGlobalWindow.cpp, MessagePort.cpp, nsJSEnvironment.cpp,
Sandbox.cpp, XPCConvert.cpp, ExportHelpers.cpp, and DataStoreService.cpp. The
rest of this diff was generated by running the following commands:
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObject\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(Binding(?:_workers)?::Wrap\((?:aCx|cx|aContext|aCtx|js), [^,)]+)\)/\1, aGivenProto)/g'
2015-03-19 17:13:33 +03:00
|
|
|
JSObject* HTMLOptionElement::WrapNode(JSContext* aCx,
|
|
|
|
JS::Handle<JSObject*> aGivenProto) {
|
2018-06-26 00:20:54 +03:00
|
|
|
return HTMLOptionElement_Binding::Wrap(aCx, this, aGivenProto);
|
2013-02-18 16:26:57 +04:00
|
|
|
}
|
|
|
|
|
2013-02-18 16:24:58 +04:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|