/* 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 "mozilla/dom/HTMLSelectElement.h" #include "ButtonControlFrame.h" #include "mozilla/BasicEvents.h" #include "mozilla/Casting.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/EventDispatcher.h" #include "mozilla/MappedDeclarationsBuilder.h" #include "mozilla/MouseEvents.h" #include "mozilla/PresShell.h" #include "mozilla/PresState.h" #include "mozilla/StaticPrefs_ui.h" #include "mozilla/TextEvents.h" #include "mozilla/dom/ContentList.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/FormData.h" #include "mozilla/dom/HTMLOptGroupElement.h" #include "mozilla/dom/HTMLOptionElement.h" #include "mozilla/dom/HTMLSelectElementBinding.h" #include "mozilla/dom/MouseEventBinding.h" #include "mozilla/dom/UnionTypes.h" #include "mozilla/dom/WindowGlobalChild.h" #include "nsComboboxControlFrame.h" #include "nsComputedDOMStyle.h" #include "nsContentCreatorFunctions.h" #include "nsContentUtils.h" #include "nsError.h" #include "nsGkAtoms.h" #include "nsIFrame.h" #include "nsLayoutUtils.h" #include "nsListControlFrame.h" #ifdef ACCESSIBILITY # include "nsAccessibilityService.h" #endif NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Select) static bool IsOptionInteractivelySelectable( const mozilla::dom::HTMLSelectElement& aSelect, mozilla::dom::HTMLOptionElement& aOption) { if (aSelect.IsOptionDisabled(&aOption)) { return false; } if (!aSelect.IsCombobox()) { return aOption.GetPrimaryFrame(); } for (mozilla::dom::Element* el = &aOption; el && el != &aSelect; el = el->GetParentElement()) { RefPtr style = nsComputedDOMStyle::GetComputedStyleNoFlush(el); if (!style) { return false; } auto display = style->StyleDisplay()->mDisplay; if (display == mozilla::StyleDisplay::None) { return false; } } return true; } static mozilla::StaticAutoPtr sIncrementalString; static mozilla::TimeStamp gLastKeyTime; static uintptr_t sLastSelectKeyHandler = 0; static nsString& GetIncrementalString() { MOZ_ASSERT(sLastSelectKeyHandler != 0); if (!sIncrementalString) { sIncrementalString = new nsString(); mozilla::ClearOnShutdown(&sIncrementalString); } return *sIncrementalString; } namespace mozilla::dom { //---------------------------------------------------------------------- // // HTMLSelectElement // // construction, destruction HTMLSelectElement::HTMLSelectElement( already_AddRefed&& aNodeInfo, FromParser aFromParser) : nsGenericHTMLFormControlElementWithState( std::move(aNodeInfo), aFromParser, FormControlType::Select), mOptions(new HTMLOptionsCollection(this, !!aFromParser)), mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown), mAutocompleteInfoState(nsContentUtils::eAutocompleteAttrState_Unknown), mIsDoneAddingChildren(!aFromParser), mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)) { SetHasWeirdParserInsertionMode(); // Set up our default state: enabled, optional, and valid. AddStatesSilently(ElementState::ENABLED | ElementState::OPTIONAL_ | ElementState::VALID); AddMutationObserver(this); } void HTMLSelectElement::SetupShadowTree() { AttachAndSetUAShadowRoot(NotifyUAWidget::No); RefPtr sr = GetShadowRoot(); if (NS_WARN_IF(!sr)) { return; } // For now, we append a