Bug 1880216 - Migrate Fenix docs into Sphinx. r=owlish,geckoview-reviewers,android...
[gecko.git] / dom / html / HTMLOptGroupElement.cpp
blob9a160b430c6f2719bd2a4513d83c0110a61ef1d4
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/EventDispatcher.h"
8 #include "mozilla/Maybe.h"
9 #include "mozilla/dom/HTMLOptGroupElement.h"
10 #include "mozilla/dom/HTMLOptGroupElementBinding.h"
11 #include "mozilla/dom/HTMLSelectElement.h" // SafeOptionListMutation
12 #include "nsGkAtoms.h"
13 #include "nsStyleConsts.h"
14 #include "nsIFrame.h"
15 #include "nsIFormControlFrame.h"
17 NS_IMPL_NS_NEW_HTML_ELEMENT(OptGroup)
19 namespace mozilla::dom {
21 /**
22 * The implementation of <optgroup>
25 HTMLOptGroupElement::HTMLOptGroupElement(
26 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
27 : nsGenericHTMLElement(std::move(aNodeInfo)) {
28 // We start off enabled
29 AddStatesSilently(ElementState::ENABLED);
32 HTMLOptGroupElement::~HTMLOptGroupElement() = default;
34 NS_IMPL_ELEMENT_CLONE(HTMLOptGroupElement)
36 void HTMLOptGroupElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
37 aVisitor.mCanHandle = false;
39 if (nsIFrame* frame = GetPrimaryFrame()) {
40 // FIXME(emilio): This poking at the style of the frame is broken unless we
41 // flush before every event handling, which we don't really want to.
42 if (frame->StyleUI()->UserInput() == StyleUserInput::None) {
43 return;
47 nsGenericHTMLElement::GetEventTargetParent(aVisitor);
50 Element* HTMLOptGroupElement::GetSelect() {
51 Element* parent = nsINode::GetParentElement();
52 if (!parent || !parent->IsHTMLElement(nsGkAtoms::select)) {
53 return nullptr;
55 return parent;
58 void HTMLOptGroupElement::InsertChildBefore(nsIContent* aKid,
59 nsIContent* aBeforeThis,
60 bool aNotify, ErrorResult& aRv) {
61 const uint32_t index =
62 aBeforeThis ? *ComputeIndexOf(aBeforeThis) : GetChildCount();
63 SafeOptionListMutation safeMutation(GetSelect(), this, aKid, index, aNotify);
64 nsGenericHTMLElement::InsertChildBefore(aKid, aBeforeThis, aNotify, aRv);
65 if (aRv.Failed()) {
66 safeMutation.MutationFailed();
70 void HTMLOptGroupElement::RemoveChildNode(nsIContent* aKid, bool aNotify) {
71 SafeOptionListMutation safeMutation(GetSelect(), this, nullptr,
72 *ComputeIndexOf(aKid), aNotify);
73 nsGenericHTMLElement::RemoveChildNode(aKid, aNotify);
76 void HTMLOptGroupElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
77 const nsAttrValue* aValue,
78 const nsAttrValue* aOldValue,
79 nsIPrincipal* aSubjectPrincipal,
80 bool aNotify) {
81 if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled) {
82 ElementState disabledStates;
83 if (aValue) {
84 disabledStates |= ElementState::DISABLED;
85 } else {
86 disabledStates |= ElementState::ENABLED;
89 ElementState oldDisabledStates = State() & ElementState::DISABLED_STATES;
90 ElementState changedStates = disabledStates ^ oldDisabledStates;
92 if (!changedStates.IsEmpty()) {
93 ToggleStates(changedStates, aNotify);
95 // All our children <option> have their :disabled state depending on our
96 // disabled attribute. We should make sure their state is updated.
97 for (nsIContent* child = nsINode::GetFirstChild(); child;
98 child = child->GetNextSibling()) {
99 if (auto optElement = HTMLOptionElement::FromNode(child)) {
100 optElement->OptGroupDisabledChanged(true);
106 return nsGenericHTMLElement::AfterSetAttr(
107 aNameSpaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
110 JSObject* HTMLOptGroupElement::WrapNode(JSContext* aCx,
111 JS::Handle<JSObject*> aGivenProto) {
112 return HTMLOptGroupElement_Binding::Wrap(aCx, this, aGivenProto);
115 } // namespace mozilla::dom