/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/. */ #ifndef mozilla_dom_HTMLSelectElement_h #define mozilla_dom_HTMLSelectElement_h
class nsContentList; class nsIDOMHTMLOptionElement; class nsIHTMLCollection; class nsISelectControlFrame;
namespace mozilla {
class ErrorResult; class EventChainPostVisitor; class EventChainPreVisitor; class SelectContentData; class PresState;
namespace dom {
class FormData; class HTMLSelectElement;
class MOZ_STACK_CLASS SafeOptionListMutation { public: /** * @param aSelect The select element which option list is being mutated. * Can be null. * @param aParent The content object which is being mutated. * @param aKid If not null, a new child element is being inserted to * aParent. Otherwise a child element will be removed. * @param aIndex The index of the content object in the parent.
*/
SafeOptionListMutation(nsIContent* aSelect, nsIContent* aParent,
nsIContent* aKid, uint32_t aIndex, bool aNotify);
~SafeOptionListMutation(); void MutationFailed() { mNeedsRebuild = true; }
private: staticvoid* operatornew(size_t) noexcept(true) { return nullptr; } staticvoidoperatordelete(void*, size_t) {} /** The select element which option list is being mutated. */
RefPtr<HTMLSelectElement> mSelect; /** true if the current mutation is the first one in the stack. */ bool mTopLevelMutation; /** true if it is known that the option list must be recreated. */ bool mNeedsRebuild; /** Whether we should be notifying when we make various method calls on
mSelect */ constbool mNotify; /** The selected option at mutation start. */
RefPtr<HTMLOptionElement> mInitialSelectedOption; /** Option list must be recreated if more than one mutation is detected. */
nsMutationGuard mGuard;
};
/** * Implementation of <select>
*/ class HTMLSelectElement final : public nsGenericHTMLFormControlElementWithState, public ConstraintValidation { public: /** * IsSelected whether to set the option(s) to true or false * * ClearAll whether to clear all other options (for example, if you * are normal-clicking on the current option) * * SetDisabled whether it is permissible to set disabled options * (for JavaScript) * * Notify whether to notify frames and such * * NoReselect no need to select something after an option is * deselected (for reset) * * InsertingOptions if an option has just been inserted some bailouts can't * be taken
*/ enumclass OptionFlag : uint8_t {
IsSelected,
ClearAll,
SetDisabled,
Notify,
NoReselect,
InsertingOptions
}; using OptionFlags = EnumSet<OptionFlag>;
/** * To be called when stuff is added under a child of the select--but *before* * they are actually added. * * @param aOptions the content that was added (usually just an option, but * could be an optgroup node with many child options) * @param aParent the parent the options were added to (could be an optgroup) * @param aContentIndex the index where the options are being added within the * parent (if the parent is an optgroup, the index within the optgroup)
*/
NS_IMETHOD WillAddOptions(nsIContent* aOptions, nsIContent* aParent,
int32_t aContentIndex, bool aNotify);
/** * To be called when stuff is removed under a child of the select--but * *before* they are actually removed. * * @param aParent the parent the option(s) are being removed from * @param aContentIndex the index of the option(s) within the parent (if the * parent is an optgroup, the index within the optgroup)
*/
NS_IMETHOD WillRemoveOptions(nsIContent* aParent, int32_t aContentIndex, bool aNotify);
/** * Checks whether an option is disabled (even if it's part of an optgroup) * * @param aIndex the index of the option to check * @return whether the option is disabled
*/
NS_IMETHOD IsOptionDisabled(int32_t aIndex, bool* aIsDisabled); bool IsOptionDisabled(HTMLOptionElement* aOption) const;
/** * Sets multiple options (or just sets startIndex if select is single) * and handles notifications and cleanup and everything under the sun. * When this method exits, the select will be in a consistent state. i.e. * if you set the last option to false, it will select an option anyway. * * @param aStartIndex the first index to set * @param aEndIndex the last index to set (set same as first index for one * option) * @param aOptionsMask determines whether to set, clear all or disable * options and whether frames are to be notified of such. * @return whether any options were actually changed
*/ bool SetOptionsSelectedByIndex(int32_t aStartIndex, int32_t aEndIndex,
OptionFlags aOptionsMask);
/** * Called when an attribute is about to be changed
*/
nsresult BindToTree(BindContext&, nsINode& aParent) override; void UnbindFromTree(UnbindContext&) override; void BeforeSetAttr(int32_t aNameSpaceID, nsAtom* aName, const nsAttrValue* aValue, bool aNotify) override; void AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, const nsAttrValue* aValue, const nsAttrValue* aOldValue,
nsIPrincipal* aSubjectPrincipal, bool aNotify) override;
void UpdateValueMissingValidityState(); void UpdateValidityElementStates(bool aNotify); /** * Insert aElement before the node given by aBefore
*/ void Add(nsGenericHTMLElement& aElement, nsGenericHTMLElement* aBefore,
ErrorResult& aError); void Add(nsGenericHTMLElement& aElement, int32_t aIndex,
ErrorResult& aError) { // If item index is out of range, insert to last. // (since beforeElement becomes null, it is inserted to last)
nsIContent* beforeContent = mOptions->GetElementAt(aIndex); return Add(aElement, nsGenericHTMLElement::FromNodeOrNull(beforeContent),
aError);
}
/** * Is this a combobox?
*/ bool IsCombobox() const { return !Multiple() && Size() <= 1; }
// Helper Methods /** * Check whether the option specified by the index is selected * @param aIndex the index * @return whether the option at the index is selected
*/ bool IsOptionSelectedByIndex(int32_t aIndex) const; /** * Starting with (and including) aStartIndex, find the first selected index * and set mSelectedIndex to it. * @param aStartIndex the index to start with
*/ void FindSelectedIndex(int32_t aStartIndex, bool aNotify); /** * Select some option if possible (generally the first non-disabled option). * @return true if something was selected, false otherwise
*/ bool SelectSomething(bool aNotify); /** * Call SelectSomething(), but only if nothing is selected * @see SelectSomething() * @return true if something was selected, false otherwise
*/ bool CheckSelectSomething(bool aNotify); /** * Called to trigger notifications of frames and fixing selected index * * @param aSelectFrame the frame for this content (could be null) * @param aIndex the index that was selected or deselected * @param aSelected whether the index was selected or deselected * @param aChangeOptionState if false, don't do anything to the * HTMLOptionElement at aIndex. If true, change * its selected state to aSelected. * @param aNotify whether to notify the style system and such
*/ void OnOptionSelected(nsISelectControlFrame* aSelectFrame, int32_t aIndex, bool aSelected, bool aChangeOptionState, bool aNotify); /** * Restore state to a particular state string (representing the options) * @param aNewSelected the state string to restore to
*/ void RestoreStateTo(const SelectContentData& aNewSelected);
// Adding options /** * Insert option(s) into the options[] array and perform notifications * @param aOptions the option or optgroup being added * @param aListIndex the index to start adding options into the list at * @param aDepth the depth of aOptions (1=direct child of select ...)
*/ void InsertOptionsIntoList(nsIContent* aOptions, int32_t aListIndex,
int32_t aDepth, bool aNotify); /** * Remove option(s) from the options[] array * @param aOptions the option or optgroup being added * @param aListIndex the index to start removing options from the list at * @param aDepth the depth of aOptions (1=direct child of select ...)
*/
nsresult RemoveOptionsFromList(nsIContent* aOptions, int32_t aListIndex,
int32_t aDepth, bool aNotify);
/** * Get the index of the first option at, under or following the content in * the select, or length of options[] if none are found * @param aOptions the content * @return the index of the first option
*/
int32_t GetOptionIndexAt(nsIContent* aOptions); /** * Get the next option following the content in question (not at or under) * (this could include siblings of the current content or siblings of the * parent or children of siblings of the parent). * @param aOptions the content * @return the index of the next option after the content
*/
int32_t GetOptionIndexAfter(nsIContent* aOptions); /** * Get the first option index at or under the content in question. * @param aOptions the content * @return the index of the first option at or under the content
*/
int32_t GetFirstOptionIndex(nsIContent* aOptions); /** * Get the first option index under the content in question, within the * range specified. * @param aOptions the content * @param aStartIndex the first child to look at * @param aEndIndex the child *after* the last child to look at * @return the index of the first option at or under the content
*/
int32_t GetFirstChildOptionIndex(nsIContent* aOptions, int32_t aStartIndex,
int32_t aEndIndex);
/** * Get the frame as an nsISelectControlFrame (MAY RETURN nullptr) * @return the select frame, or null
*/
nsISelectControlFrame* GetSelectFrame();
/** * Helper method for dispatching ContentReset notifications to list box * frames.
*/ void DispatchContentReset();
/** * Rebuilds the options array from scratch as a fallback in error cases.
*/ void RebuildOptionsArray(bool aNotify);
/** * Marks the selectedOptions list as dirty, so that it'll populate itself * again.
*/ void UpdateSelectedOptions();
void SetUserInteracted(bool) final;
/** The options[] array */
RefPtr<HTMLOptionsCollection> mOptions;
nsContentUtils::AutocompleteAttrState mAutocompleteAttrState;
nsContentUtils::AutocompleteAttrState mAutocompleteInfoState; /** false if the parser is in the middle of adding children. */ bool mIsDoneAddingChildren : 1; /** true if our disabled state has changed from the default **/ bool mDisabledChanged : 1; /** true if child nodes are being added or removed. * Used by SafeOptionListMutation.
*/ bool mMutating : 1; /** * True if DoneAddingChildren will get called but shouldn't restore state.
*/ bool mInhibitStateRestoration : 1; /** https://html.spec.whatwg.org/#user-interacted */ bool mUserInteracted : 1; /** True if the default selected option has been set. */ bool mDefaultSelectionSet : 1; /** True if we're open in the parent process */ bool mIsOpenInParentProcess : 1;
/** The number of non-options as children of the select */
uint32_t mNonOptionChildren; /** The number of optgroups anywhere under the select */
uint32_t mOptGroupCount; /** * The current selected index for selectedIndex (will be the first selected * index if multiple are selected)
*/
int32_t mSelectedIndex; /** * The temporary restore state in case we try to restore before parser is * done adding options
*/
UniquePtr<SelectContentData> mRestoreState;
/** * The live list of selected options.
*/
RefPtr<nsContentList> mSelectedOptions;
/** * The current displayed preview text.
*/
nsString mPreviewValue;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.