2015-05-03 19:32:37 +00: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 11:12:37 +00: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/. */
|
2013-04-04 07:03:33 +00:00
|
|
|
#ifndef mozilla_dom_HTMLSelectElement_h
|
|
|
|
#define mozilla_dom_HTMLSelectElement_h
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2013-05-29 20:43:41 +00:00
|
|
|
#include "mozilla/Attributes.h"
|
2007-08-28 07:09:32 +00:00
|
|
|
#include "nsGenericHTMLElement.h"
|
|
|
|
#include "nsIDOMHTMLSelectElement.h"
|
2010-08-21 18:52:49 +00:00
|
|
|
#include "nsIConstraintValidation.h"
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2013-04-13 07:01:04 +00:00
|
|
|
#include "mozilla/dom/BindingDeclarations.h"
|
2013-03-17 07:55:17 +00:00
|
|
|
#include "mozilla/dom/HTMLOptionsCollection.h"
|
|
|
|
#include "mozilla/ErrorResult.h"
|
2007-08-28 07:09:32 +00:00
|
|
|
#include "nsCheapSets.h"
|
2013-03-17 07:55:17 +00:00
|
|
|
#include "nsCOMPtr.h"
|
2012-07-27 14:03:27 +00:00
|
|
|
#include "nsError.h"
|
2013-06-19 14:24:37 +00:00
|
|
|
#include "mozilla/dom/HTMLFormElement.h"
|
2014-07-24 14:55:00 +00:00
|
|
|
#include "nsContentUtils.h"
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2013-09-02 17:23:27 +00:00
|
|
|
class nsContentList;
|
2013-03-17 07:55:17 +00:00
|
|
|
class nsIDOMHTMLOptionElement;
|
2013-09-02 17:23:27 +00:00
|
|
|
class nsIHTMLCollection;
|
2013-03-17 07:55:17 +00:00
|
|
|
class nsISelectControlFrame;
|
|
|
|
class nsPresState;
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2013-04-04 07:03:33 +00:00
|
|
|
namespace mozilla {
|
2014-03-18 04:48:19 +00:00
|
|
|
|
2014-03-18 04:48:20 +00:00
|
|
|
class EventChainPostVisitor;
|
2014-03-18 04:48:19 +00:00
|
|
|
class EventChainPreVisitor;
|
|
|
|
|
2013-04-04 07:03:33 +00:00
|
|
|
namespace dom {
|
|
|
|
|
|
|
|
class HTMLSelectElement;
|
|
|
|
|
2008-12-12 19:25:22 +00:00
|
|
|
#define NS_SELECT_STATE_IID \
|
|
|
|
{ /* 4db54c7c-d159-455f-9d8e-f60ee466dbf3 */ \
|
|
|
|
0x4db54c7c, \
|
|
|
|
0xd159, \
|
|
|
|
0x455f, \
|
|
|
|
{0x9d, 0x8e, 0xf6, 0x0e, 0xe4, 0x66, 0xdb, 0xf3} \
|
|
|
|
}
|
2007-08-28 07:09:32 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The restore state used by select
|
|
|
|
*/
|
2013-04-04 07:03:33 +00:00
|
|
|
class SelectState : public nsISupports
|
|
|
|
{
|
2007-08-28 07:09:32 +00:00
|
|
|
public:
|
2013-04-04 07:03:33 +00:00
|
|
|
SelectState()
|
2007-08-28 07:09:32 +00:00
|
|
|
{
|
|
|
|
}
|
2008-12-12 19:25:22 +00:00
|
|
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_SELECT_STATE_IID)
|
2007-08-28 07:09:32 +00:00
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
void PutOption(int32_t aIndex, const nsAString& aValue)
|
2007-08-28 07:09:32 +00:00
|
|
|
{
|
|
|
|
// If the option is empty, store the index. If not, store the value.
|
|
|
|
if (aValue.IsEmpty()) {
|
|
|
|
mIndices.Put(aIndex);
|
|
|
|
} else {
|
|
|
|
mValues.Put(aValue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
bool ContainsOption(int32_t aIndex, const nsAString& aValue)
|
2007-08-28 07:09:32 +00:00
|
|
|
{
|
|
|
|
return mValues.Contains(aValue) || mIndices.Contains(aIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2014-06-25 02:09:15 +00:00
|
|
|
virtual ~SelectState()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2012-02-10 19:30:40 +00:00
|
|
|
nsCheapSet<nsStringHashKey> mValues;
|
|
|
|
nsCheapSet<nsUint32HashKey> mIndices;
|
2007-08-28 07:09:32 +00:00
|
|
|
};
|
|
|
|
|
2014-03-28 08:45:02 +00:00
|
|
|
NS_DEFINE_STATIC_IID_ACCESSOR(SelectState, NS_SELECT_STATE_IID)
|
|
|
|
|
2013-04-12 03:20:09 +00:00
|
|
|
class MOZ_STACK_CLASS SafeOptionListMutation
|
2007-08-28 07:09:32 +00:00
|
|
|
{
|
|
|
|
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.
|
|
|
|
*/
|
2013-04-04 07:03:33 +00:00
|
|
|
SafeOptionListMutation(nsIContent* aSelect, nsIContent* aParent,
|
|
|
|
nsIContent* aKid, uint32_t aIndex, bool aNotify);
|
|
|
|
~SafeOptionListMutation();
|
2011-10-17 14:59:28 +00:00
|
|
|
void MutationFailed() { mNeedsRebuild = true; }
|
2007-08-28 07:09:32 +00:00
|
|
|
private:
|
|
|
|
static void* operator new(size_t) CPP_THROW_NEW { return 0; }
|
|
|
|
static void operator delete(void*, size_t) {}
|
|
|
|
/** The select element which option list is being mutated. */
|
2013-04-04 07:03:33 +00:00
|
|
|
nsRefPtr<HTMLSelectElement> mSelect;
|
2011-10-17 14:59:28 +00:00
|
|
|
/** true if the current mutation is the first one in the stack. */
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mTopLevelMutation;
|
2011-10-17 14:59:28 +00:00
|
|
|
/** true if it is known that the option list must be recreated. */
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mNeedsRebuild;
|
2007-08-28 07:09:32 +00:00
|
|
|
/** Option list must be recreated if more than one mutation is detected. */
|
|
|
|
nsMutationGuard mGuard;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementation of <select>
|
|
|
|
*/
|
2015-03-21 16:28:04 +00:00
|
|
|
class HTMLSelectElement final : public nsGenericHTMLFormElementWithState,
|
2015-03-27 18:52:19 +00:00
|
|
|
public nsIDOMHTMLSelectElement,
|
|
|
|
public nsIConstraintValidation
|
2007-08-28 07:09:32 +00:00
|
|
|
{
|
|
|
|
public:
|
2013-09-28 19:04:20 +00:00
|
|
|
/**
|
|
|
|
* IS_SELECTED whether to set the option(s) to true or false
|
|
|
|
*
|
|
|
|
* CLEAR_ALL whether to clear all other options (for example, if you
|
|
|
|
* are normal-clicking on the current option)
|
|
|
|
*
|
|
|
|
* SET_DISABLED whether it is permissible to set disabled options
|
|
|
|
* (for JavaScript)
|
|
|
|
*
|
|
|
|
* NOTIFY whether to notify frames and such
|
|
|
|
*/
|
|
|
|
enum OptionType {
|
|
|
|
IS_SELECTED = 1 << 0,
|
|
|
|
CLEAR_ALL = 1 << 1,
|
|
|
|
SET_DISABLED = 1 << 2,
|
|
|
|
NOTIFY = 1 << 3
|
|
|
|
};
|
|
|
|
|
2010-09-02 20:12:47 +00:00
|
|
|
using nsIConstraintValidation::GetValidationMessage;
|
|
|
|
|
2014-09-02 00:49:25 +00:00
|
|
|
explicit HTMLSelectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
|
|
|
|
FromParser aFromParser = NOT_FROM_PARSER);
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2013-04-04 07:03:33 +00:00
|
|
|
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLSelectElement, select)
|
2012-09-26 14:17:51 +00:00
|
|
|
|
2007-08-28 07:09:32 +00:00
|
|
|
// nsISupports
|
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
|
|
|
2015-03-21 16:28:04 +00:00
|
|
|
virtual int32_t TabIndexDefault() override;
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2015-01-20 20:39:28 +00:00
|
|
|
// Element
|
2015-03-21 16:28:04 +00:00
|
|
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override
|
2015-01-20 20:39:28 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-08-28 07:09:32 +00:00
|
|
|
// nsIDOMHTMLSelectElement
|
|
|
|
NS_DECL_NSIDOMHTMLSELECTELEMENT
|
|
|
|
|
2013-02-14 20:54:23 +00:00
|
|
|
// WebIdl HTMLSelectElement
|
|
|
|
bool Autofocus() const
|
|
|
|
{
|
|
|
|
return GetBoolAttr(nsGkAtoms::autofocus);
|
|
|
|
}
|
2013-04-04 07:03:33 +00:00
|
|
|
void SetAutofocus(bool aVal, ErrorResult& aRv)
|
2013-02-14 20:54:23 +00:00
|
|
|
{
|
|
|
|
SetHTMLBoolAttr(nsGkAtoms::autofocus, aVal, aRv);
|
|
|
|
}
|
2014-07-24 14:55:00 +00:00
|
|
|
void GetAutocomplete(DOMString& aValue);
|
|
|
|
void SetAutocomplete(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
SetHTMLAttr(nsGkAtoms::autocomplete, aValue, aRv);
|
|
|
|
}
|
2013-02-14 20:54:23 +00:00
|
|
|
bool Disabled() const
|
|
|
|
{
|
|
|
|
return GetBoolAttr(nsGkAtoms::disabled);
|
|
|
|
}
|
2013-04-04 07:03:33 +00:00
|
|
|
void SetDisabled(bool aVal, ErrorResult& aRv)
|
2013-02-14 20:54:23 +00:00
|
|
|
{
|
|
|
|
SetHTMLBoolAttr(nsGkAtoms::disabled, aVal, aRv);
|
|
|
|
}
|
2013-06-19 14:24:37 +00:00
|
|
|
HTMLFormElement* GetForm() const
|
2013-02-14 20:54:23 +00:00
|
|
|
{
|
2013-08-02 01:21:31 +00:00
|
|
|
return nsGenericHTMLFormElementWithState::GetForm();
|
2013-02-14 20:54:23 +00:00
|
|
|
}
|
|
|
|
bool Multiple() const
|
|
|
|
{
|
|
|
|
return GetBoolAttr(nsGkAtoms::multiple);
|
|
|
|
}
|
2013-04-04 07:03:33 +00:00
|
|
|
void SetMultiple(bool aVal, ErrorResult& aRv)
|
2013-02-14 20:54:23 +00:00
|
|
|
{
|
|
|
|
SetHTMLBoolAttr(nsGkAtoms::multiple, aVal, aRv);
|
|
|
|
}
|
2013-04-13 07:01:04 +00:00
|
|
|
// Uses XPCOM GetName.
|
|
|
|
void SetName(const nsAString& aName, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
SetHTMLAttr(nsGkAtoms::name, aName, aRv);
|
|
|
|
}
|
|
|
|
bool Required() const
|
|
|
|
{
|
|
|
|
return GetBoolAttr(nsGkAtoms::required);
|
|
|
|
}
|
|
|
|
void SetRequired(bool aVal, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
SetHTMLBoolAttr(nsGkAtoms::required, aVal, aRv);
|
|
|
|
}
|
|
|
|
uint32_t Size() const
|
2013-03-20 01:47:52 +00:00
|
|
|
{
|
2013-04-04 07:03:50 +00:00
|
|
|
return GetUnsignedIntAttr(nsGkAtoms::size, 0);
|
2013-03-20 01:47:52 +00:00
|
|
|
}
|
2013-04-04 07:03:33 +00:00
|
|
|
void SetSize(uint32_t aSize, ErrorResult& aRv)
|
2013-03-20 01:47:52 +00:00
|
|
|
{
|
2013-04-04 07:03:50 +00:00
|
|
|
SetUnsignedIntAttr(nsGkAtoms::size, aSize, aRv);
|
2013-03-20 01:47:52 +00:00
|
|
|
}
|
2013-04-13 07:01:04 +00:00
|
|
|
|
|
|
|
// Uses XPCOM GetType.
|
|
|
|
|
|
|
|
HTMLOptionsCollection* Options() const
|
2013-02-14 20:54:23 +00:00
|
|
|
{
|
2013-04-13 07:01:04 +00:00
|
|
|
return mOptions;
|
2013-02-14 20:54:23 +00:00
|
|
|
}
|
2013-04-13 07:01:04 +00:00
|
|
|
uint32_t Length() const
|
2013-02-14 20:54:23 +00:00
|
|
|
{
|
2013-04-13 07:01:04 +00:00
|
|
|
return mOptions->Length();
|
2013-02-14 20:54:23 +00:00
|
|
|
}
|
2013-07-24 07:36:59 +00:00
|
|
|
void SetLength(uint32_t aLength, ErrorResult& aRv);
|
2013-04-13 07:01:04 +00:00
|
|
|
Element* IndexedGetter(uint32_t aIdx, bool& aFound) const
|
2013-02-14 20:54:23 +00:00
|
|
|
{
|
2013-04-13 07:01:04 +00:00
|
|
|
return mOptions->IndexedGetter(aIdx, aFound);
|
2013-02-14 20:54:23 +00:00
|
|
|
}
|
2013-04-13 07:01:04 +00:00
|
|
|
HTMLOptionElement* Item(uint32_t aIdx) const
|
2013-02-14 20:54:23 +00:00
|
|
|
{
|
2013-04-13 07:01:04 +00:00
|
|
|
return mOptions->ItemAsOption(aIdx);
|
2013-02-14 20:54:23 +00:00
|
|
|
}
|
2013-06-01 06:56:34 +00:00
|
|
|
HTMLOptionElement* NamedItem(const nsAString& aName) const
|
2013-02-14 20:54:23 +00:00
|
|
|
{
|
2013-06-01 06:56:34 +00:00
|
|
|
return mOptions->GetNamedItem(aName);
|
2013-02-14 20:54:23 +00:00
|
|
|
}
|
2013-04-13 07:01:04 +00:00
|
|
|
void Add(const HTMLOptionElementOrHTMLOptGroupElement& aElement,
|
|
|
|
const Nullable<HTMLElementOrLong>& aBefore,
|
|
|
|
ErrorResult& aRv);
|
|
|
|
// Uses XPCOM Remove.
|
|
|
|
void IndexedSetter(uint32_t aIndex, HTMLOptionElement* aOption,
|
|
|
|
ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
mOptions->IndexedSetter(aIndex, aOption, aRv);
|
|
|
|
}
|
|
|
|
|
2013-09-02 17:23:27 +00:00
|
|
|
static bool MatchSelectedOptions(nsIContent* aContent, int32_t, nsIAtom*,
|
|
|
|
void*);
|
|
|
|
|
|
|
|
nsIHTMLCollection* SelectedOptions();
|
|
|
|
|
2013-02-14 20:54:23 +00:00
|
|
|
int32_t SelectedIndex() const
|
|
|
|
{
|
|
|
|
return mSelectedIndex;
|
|
|
|
}
|
2013-04-04 07:03:33 +00:00
|
|
|
void SetSelectedIndex(int32_t aIdx, ErrorResult& aRv)
|
2013-02-14 20:54:23 +00:00
|
|
|
{
|
|
|
|
aRv = SetSelectedIndexInternal(aIdx, true);
|
|
|
|
}
|
2013-04-13 07:01:04 +00:00
|
|
|
void GetValue(DOMString& aValue);
|
|
|
|
// Uses XPCOM SetValue.
|
|
|
|
|
|
|
|
// nsIConstraintValidation::WillValidate is fine.
|
|
|
|
// nsIConstraintValidation::Validity() is fine.
|
|
|
|
// nsIConstraintValidation::GetValidationMessage() is fine.
|
|
|
|
// nsIConstraintValidation::CheckValidity() is fine.
|
|
|
|
using nsIConstraintValidation::CheckValidity;
|
|
|
|
// nsIConstraintValidation::SetCustomValidity() is fine.
|
|
|
|
|
2013-04-13 07:08:47 +00:00
|
|
|
using nsINode::Remove;
|
|
|
|
|
2013-02-14 20:54:23 +00:00
|
|
|
|
2013-04-13 07:01:59 +00:00
|
|
|
// nsINode
|
2015-03-21 16:28:04 +00:00
|
|
|
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
2013-04-13 07:01:59 +00:00
|
|
|
|
2007-08-28 07:09:32 +00:00
|
|
|
// nsIContent
|
2015-03-21 16:28:04 +00:00
|
|
|
virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
|
2014-03-18 04:48:20 +00:00
|
|
|
virtual nsresult PostHandleEvent(
|
2015-03-21 16:28:04 +00:00
|
|
|
EventChainPostVisitor& aVisitor) override;
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2015-03-21 16:28:04 +00:00
|
|
|
virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable, int32_t* aTabIndex) override;
|
2012-08-22 15:56:38 +00:00
|
|
|
virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
|
2015-03-21 16:28:04 +00:00
|
|
|
bool aNotify) override;
|
|
|
|
virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) override;
|
2007-08-28 07:09:32 +00:00
|
|
|
|
|
|
|
// Overriden nsIFormControl methods
|
2015-03-21 16:28:04 +00:00
|
|
|
NS_IMETHOD_(uint32_t) GetType() const override { return NS_FORM_SELECT; }
|
|
|
|
NS_IMETHOD Reset() override;
|
|
|
|
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) override;
|
|
|
|
NS_IMETHOD SaveState() override;
|
|
|
|
virtual bool RestoreState(nsPresState* aState) override;
|
|
|
|
virtual bool IsDisabledForEvents(uint32_t aMessage) override;
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2015-03-21 16:28:04 +00:00
|
|
|
virtual void FieldSetDisabledChanged(bool aNotify) override;
|
2010-09-18 21:33:16 +00:00
|
|
|
|
2015-03-21 16:28:04 +00:00
|
|
|
EventStates IntrinsicState() const override;
|
2010-08-19 00:03:20 +00:00
|
|
|
|
2011-04-12 12:32:01 +00:00
|
|
|
/**
|
|
|
|
* 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,
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t aContentIndex,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool aNotify);
|
2011-04-12 12:32:01 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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,
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t aContentIndex,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool aNotify);
|
2011-04-12 12:32:01 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2012-08-22 15:56:38 +00:00
|
|
|
NS_IMETHOD IsOptionDisabled(int32_t aIndex,
|
2013-02-18 12:24:58 +00:00
|
|
|
bool* aIsDisabled);
|
2013-07-24 07:31:49 +00:00
|
|
|
bool IsOptionDisabled(HTMLOptionElement* aOption);
|
2011-04-12 12:32:01 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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)
|
2013-09-28 19:04:20 +00:00
|
|
|
* @param aOptionsMask determines whether to set, clear all or disable
|
|
|
|
* options and whether frames are to be notified of such.
|
2011-04-12 12:32:01 +00:00
|
|
|
* @return whether any options were actually changed
|
|
|
|
*/
|
2013-07-24 07:37:14 +00:00
|
|
|
bool SetOptionsSelectedByIndex(int32_t aStartIndex,
|
|
|
|
int32_t aEndIndex,
|
2013-09-28 19:04:20 +00:00
|
|
|
uint32_t aOptionsMask);
|
2011-04-12 12:32:01 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Finds the index of a given option element
|
|
|
|
*
|
|
|
|
* @param aOption the option to get the index of
|
|
|
|
* @param aStartIndex the index to start looking at
|
|
|
|
* @param aForward TRUE to look forward, FALSE to look backward
|
|
|
|
* @return the option index
|
|
|
|
*/
|
|
|
|
NS_IMETHOD GetOptionIndex(nsIDOMHTMLOptionElement* aOption,
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t aStartIndex,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool aForward,
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t* aIndex);
|
2011-04-12 12:32:01 +00:00
|
|
|
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* Called when an attribute is about to be changed
|
|
|
|
*/
|
2010-09-18 21:33:16 +00:00
|
|
|
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|
|
|
nsIContent* aBindingParent,
|
2015-03-21 16:28:04 +00:00
|
|
|
bool aCompileEventHandlers) override;
|
|
|
|
virtual void UnbindFromTree(bool aDeep, bool aNullParent) override;
|
2012-08-22 15:56:38 +00:00
|
|
|
virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
2012-02-14 02:00:56 +00:00
|
|
|
const nsAttrValueOrString* aValue,
|
2015-03-21 16:28:04 +00:00
|
|
|
bool aNotify) override;
|
2012-08-22 15:56:38 +00:00
|
|
|
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
2015-03-21 16:28:04 +00:00
|
|
|
const nsAttrValue* aValue, bool aNotify) override;
|
2012-08-22 15:56:38 +00:00
|
|
|
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
2015-03-21 16:28:04 +00:00
|
|
|
bool aNotify) override;
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2015-03-21 16:28:04 +00:00
|
|
|
virtual void DoneAddingChildren(bool aHaveNotified) override;
|
|
|
|
virtual bool IsDoneAddingChildren() override {
|
2010-11-24 10:09:01 +00:00
|
|
|
return mIsDoneAddingChildren;
|
|
|
|
}
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
virtual bool ParseAttribute(int32_t aNamespaceID,
|
2007-08-28 07:09:32 +00:00
|
|
|
nsIAtom* aAttribute,
|
|
|
|
const nsAString& aValue,
|
2015-03-21 16:28:04 +00:00
|
|
|
nsAttrValue& aResult) override;
|
|
|
|
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
|
2007-08-28 07:09:32 +00:00
|
|
|
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
2015-03-21 16:28:04 +00:00
|
|
|
int32_t aModType) const override;
|
|
|
|
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2015-03-21 16:28:04 +00:00
|
|
|
virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2013-04-04 07:03:33 +00:00
|
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLSelectElement,
|
2013-08-02 01:21:31 +00:00
|
|
|
nsGenericHTMLFormElementWithState)
|
2007-08-28 07:09:32 +00:00
|
|
|
|
2013-03-17 07:55:17 +00:00
|
|
|
HTMLOptionsCollection* GetOptions()
|
2010-05-09 18:32:57 +00:00
|
|
|
{
|
|
|
|
return mOptions;
|
|
|
|
}
|
|
|
|
|
2010-09-18 21:33:16 +00:00
|
|
|
// nsIConstraintValidation
|
2010-11-16 23:41:19 +00:00
|
|
|
nsresult GetValidationMessage(nsAString& aValidationMessage,
|
2015-03-21 16:28:04 +00:00
|
|
|
ValidityStateType aType) override;
|
2010-09-18 21:33:16 +00:00
|
|
|
|
2014-05-06 17:19:00 +00:00
|
|
|
void UpdateValueMissingValidityState();
|
2012-09-05 20:49:53 +00:00
|
|
|
/**
|
|
|
|
* Insert aElement before the node given by aBefore
|
|
|
|
*/
|
2012-11-10 23:30:15 +00:00
|
|
|
void Add(nsGenericHTMLElement& aElement, nsGenericHTMLElement* aBefore,
|
2013-04-04 07:03:33 +00:00
|
|
|
ErrorResult& aError);
|
|
|
|
void Add(nsGenericHTMLElement& aElement, int32_t aIndex, ErrorResult& aError)
|
2012-09-05 20:49:53 +00:00
|
|
|
{
|
|
|
|
// If item index is out of range, insert to last.
|
|
|
|
// (since beforeElement becomes null, it is inserted to last)
|
2012-11-10 23:30:15 +00:00
|
|
|
nsIContent* beforeContent = mOptions->GetElementAt(aIndex);
|
|
|
|
return Add(aElement, nsGenericHTMLElement::FromContentOrNull(beforeContent),
|
|
|
|
aError);
|
2012-09-05 20:49:53 +00:00
|
|
|
}
|
|
|
|
|
2013-06-12 07:00:08 +00:00
|
|
|
/**
|
|
|
|
* Is this a combobox?
|
|
|
|
*/
|
|
|
|
bool IsCombobox() const
|
|
|
|
{
|
|
|
|
return !Multiple() && Size() <= 1;
|
|
|
|
}
|
|
|
|
|
2007-08-28 07:09:32 +00:00
|
|
|
protected:
|
2014-07-08 21:23:16 +00:00
|
|
|
virtual ~HTMLSelectElement();
|
|
|
|
|
2013-04-04 07:03:33 +00:00
|
|
|
friend class SafeOptionListMutation;
|
2007-08-28 07:09:32 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
*/
|
2012-08-22 15:56:38 +00:00
|
|
|
bool IsOptionSelectedByIndex(int32_t aIndex);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* Starting with (and including) aStartIndex, find the first selected index
|
|
|
|
* and set mSelectedIndex to it.
|
|
|
|
* @param aStartIndex the index to start with
|
|
|
|
*/
|
2012-08-22 15:56:38 +00:00
|
|
|
void FindSelectedIndex(int32_t aStartIndex, bool aNotify);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* Select some option if possible (generally the first non-disabled option).
|
|
|
|
* @return true if something was selected, false otherwise
|
|
|
|
*/
|
2011-09-29 06:19:26 +00:00
|
|
|
bool SelectSomething(bool aNotify);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* Call SelectSomething(), but only if nothing is selected
|
|
|
|
* @see SelectSomething()
|
|
|
|
* @return true if something was selected, false otherwise
|
|
|
|
*/
|
2011-09-29 06:19:26 +00:00
|
|
|
bool CheckSelectSomething(bool aNotify);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* 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
|
2007-12-04 17:14:20 +00:00
|
|
|
* @param aChangeOptionState if false, don't do anything to the
|
2013-02-18 12:24:58 +00:00
|
|
|
* HTMLOptionElement at aIndex. If true, change
|
2007-12-04 17:14:20 +00:00
|
|
|
* its selected state to aSelected.
|
2007-08-28 07:09:32 +00:00
|
|
|
* @param aNotify whether to notify the style system and such
|
|
|
|
*/
|
|
|
|
void OnOptionSelected(nsISelectControlFrame* aSelectFrame,
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t aIndex,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool aSelected,
|
|
|
|
bool aChangeOptionState,
|
|
|
|
bool aNotify);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* Restore state to a particular state string (representing the options)
|
|
|
|
* @param aNewSelected the state string to restore to
|
|
|
|
*/
|
2013-04-04 07:03:33 +00:00
|
|
|
void RestoreStateTo(SelectState* aNewSelected);
|
2007-08-28 07:09:32 +00:00
|
|
|
|
|
|
|
// 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 ...)
|
|
|
|
*/
|
2013-07-24 07:35:08 +00:00
|
|
|
void InsertOptionsIntoList(nsIContent* aOptions,
|
|
|
|
int32_t aListIndex,
|
|
|
|
int32_t aDepth,
|
|
|
|
bool aNotify);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* 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,
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t aListIndex,
|
|
|
|
int32_t aDepth,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool aNotify);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* Insert option(s) into the options[] array (called by InsertOptionsIntoList)
|
|
|
|
* @param aOptions the option or optgroup being added
|
|
|
|
* @param aInsertIndex the index to start adding options into the list at
|
|
|
|
* @param aDepth the depth of aOptions (1=direct child of select ...)
|
|
|
|
*/
|
2013-07-24 07:35:08 +00:00
|
|
|
void InsertOptionsIntoListRecurse(nsIContent* aOptions,
|
|
|
|
int32_t* aInsertIndex,
|
|
|
|
int32_t aDepth);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* Remove option(s) from the options[] array (called by RemoveOptionsFromList)
|
|
|
|
* @param aOptions the option or optgroup being added
|
|
|
|
* @param aListIndex the index to start removing options from the list at
|
|
|
|
* @param aNumRemoved the number removed so far [OUT]
|
|
|
|
* @param aDepth the depth of aOptions (1=direct child of select ...)
|
|
|
|
*/
|
|
|
|
nsresult RemoveOptionsFromListRecurse(nsIContent* aOptions,
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t aRemoveIndex,
|
|
|
|
int32_t* aNumRemoved,
|
|
|
|
int32_t aDepth);
|
2010-11-16 23:41:19 +00:00
|
|
|
|
|
|
|
// nsIConstraintValidation
|
|
|
|
void UpdateBarredFromConstraintValidation();
|
|
|
|
bool IsValueMissing();
|
|
|
|
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* Find out how deep this content is from the select (1=direct child)
|
|
|
|
* @param aContent the content to check
|
|
|
|
* @return the depth
|
|
|
|
*/
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t GetContentDepth(nsIContent* aContent);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t GetOptionIndexAt(nsIContent* aOptions);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t GetOptionIndexAfter(nsIContent* aOptions);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t GetFirstOptionIndex(nsIContent* aOptions);
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t GetFirstChildOptionIndex(nsIContent* aOptions,
|
|
|
|
int32_t aStartIndex,
|
|
|
|
int32_t aEndIndex);
|
2007-08-28 07:09:32 +00:00
|
|
|
|
|
|
|
/**
|
2013-04-03 01:14:24 +00:00
|
|
|
* Get the frame as an nsISelectControlFrame (MAY RETURN nullptr)
|
2007-08-28 07:09:32 +00:00
|
|
|
* @return the select frame, or null
|
|
|
|
*/
|
2013-02-18 12:24:58 +00:00
|
|
|
nsISelectControlFrame* GetSelectFrame();
|
2007-08-28 07:09:32 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper method for dispatching ContentReset notifications to list
|
|
|
|
* and combo box frames.
|
|
|
|
*/
|
|
|
|
void DispatchContentReset();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Rebuilds the options array from scratch as a fallback in error cases.
|
|
|
|
*/
|
2011-09-29 06:19:26 +00:00
|
|
|
void RebuildOptionsArray(bool aNotify);
|
2007-08-28 07:09:32 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
void VerifyOptionsArray();
|
|
|
|
#endif
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
nsresult SetSelectedIndexInternal(int32_t aIndex, bool aNotify);
|
2010-11-24 10:09:01 +00:00
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
void SetSelectionChanged(bool aValue, bool aNotify);
|
2010-11-24 10:09:01 +00:00
|
|
|
|
2013-09-02 17:23:27 +00:00
|
|
|
/**
|
|
|
|
* Marks the selectedOptions list as dirty, so that it'll populate itself
|
|
|
|
* again.
|
|
|
|
*/
|
|
|
|
void UpdateSelectedOptions();
|
|
|
|
|
2010-11-24 10:09:31 +00:00
|
|
|
/**
|
2011-01-20 11:05:29 +00:00
|
|
|
* Return whether an element should have a validity UI.
|
|
|
|
* (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes).
|
2010-11-24 10:09:31 +00:00
|
|
|
*
|
2011-01-20 11:05:29 +00:00
|
|
|
* @return Whether the element should have a validity UI.
|
2010-11-24 10:09:31 +00:00
|
|
|
*/
|
2011-01-20 11:05:29 +00:00
|
|
|
bool ShouldShowValidityUI() const {
|
2010-11-24 10:09:31 +00:00
|
|
|
/**
|
2011-01-20 11:05:29 +00:00
|
|
|
* Always show the validity UI if the form has already tried to be submitted
|
|
|
|
* but was invalid.
|
2010-11-24 10:09:31 +00:00
|
|
|
*
|
2011-01-20 11:05:29 +00:00
|
|
|
* Otherwise, show the validity UI if the selection has been changed.
|
2010-11-24 10:09:31 +00:00
|
|
|
*/
|
2011-01-27 13:51:45 +00:00
|
|
|
if (mForm && mForm->HasEverTriedInvalidSubmit()) {
|
|
|
|
return true;
|
2010-12-17 23:26:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return mSelectionHasChanged;
|
2010-11-24 10:09:31 +00:00
|
|
|
}
|
2010-12-17 23:26:24 +00:00
|
|
|
|
2007-08-28 07:09:32 +00:00
|
|
|
/** The options[] array */
|
2013-03-17 07:55:17 +00:00
|
|
|
nsRefPtr<HTMLOptionsCollection> mOptions;
|
2014-07-24 14:55:00 +00:00
|
|
|
nsContentUtils::AutocompleteAttrState mAutocompleteAttrState;
|
2007-08-28 07:09:32 +00:00
|
|
|
/** false if the parser is in the middle of adding children. */
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mIsDoneAddingChildren;
|
2007-08-28 07:09:32 +00:00
|
|
|
/** true if our disabled state has changed from the default **/
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mDisabledChanged;
|
2007-08-28 07:09:32 +00:00
|
|
|
/** true if child nodes are being added or removed.
|
2013-04-04 07:03:33 +00:00
|
|
|
* Used by SafeOptionListMutation.
|
2007-08-28 07:09:32 +00:00
|
|
|
*/
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mMutating;
|
2010-06-09 06:45:32 +00:00
|
|
|
/**
|
|
|
|
* True if DoneAddingChildren will get called but shouldn't restore state.
|
|
|
|
*/
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mInhibitStateRestoration;
|
2010-11-24 10:09:01 +00:00
|
|
|
/**
|
|
|
|
* True if the selection has changed since the element's creation.
|
|
|
|
*/
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mSelectionHasChanged;
|
2010-11-24 10:09:01 +00:00
|
|
|
/**
|
|
|
|
* True if the default selected option has been set.
|
|
|
|
*/
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mDefaultSelectionSet;
|
2010-11-24 10:09:31 +00:00
|
|
|
/**
|
|
|
|
* True if :-moz-ui-invalid can be shown.
|
|
|
|
*/
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mCanShowInvalidUI;
|
2010-11-24 10:09:31 +00:00
|
|
|
/**
|
|
|
|
* True if :-moz-ui-valid can be shown.
|
|
|
|
*/
|
2011-09-29 06:19:26 +00:00
|
|
|
bool mCanShowValidUI;
|
2010-11-24 10:09:01 +00:00
|
|
|
|
2007-08-28 07:09:32 +00:00
|
|
|
/** The number of non-options as children of the select */
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t mNonOptionChildren;
|
2007-08-28 07:09:32 +00:00
|
|
|
/** The number of optgroups anywhere under the select */
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t mOptGroupCount;
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* The current selected index for selectedIndex (will be the first selected
|
|
|
|
* index if multiple are selected)
|
|
|
|
*/
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t mSelectedIndex;
|
2007-08-28 07:09:32 +00:00
|
|
|
/**
|
|
|
|
* The temporary restore state in case we try to restore before parser is
|
|
|
|
* done adding options
|
|
|
|
*/
|
2013-04-04 07:03:33 +00:00
|
|
|
nsCOMPtr<SelectState> mRestoreState;
|
2013-09-02 17:23:27 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The live list of selected options.
|
|
|
|
*/
|
|
|
|
nsRefPtr<nsContentList> mSelectedOptions;
|
2013-11-19 19:21:29 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
|
|
|
nsRuleData* aData);
|
2007-08-28 07:09:32 +00:00
|
|
|
};
|
|
|
|
|
2013-04-04 07:03:33 +00:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_dom_HTMLSelectElement_h
|