зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1850295 - Update :user-{valid,invalid} to follow the spec. r=smaug
(Modulo open spec issues linked in comments) Differential Revision: https://phabricator.services.mozilla.com/D196986
This commit is contained in:
Родитель
1aa61dcd48
Коммит
71838e2f11
|
@ -69,7 +69,7 @@ class HTMLButtonElement final : public nsGenericHTMLFormControlElementWithState,
|
|||
void DoneCreatingElement() override;
|
||||
|
||||
void UpdateBarredFromConstraintValidation();
|
||||
void UpdateValidityElementStates(bool aNotify) final;
|
||||
void UpdateValidityElementStates(bool aNotify);
|
||||
/**
|
||||
* Called when an attribute is about to be changed
|
||||
*/
|
||||
|
|
|
@ -49,7 +49,7 @@ class HTMLElement final : public nsGenericHTMLFormElement {
|
|||
void AfterClearForm(bool aUnbindOrDelete) override;
|
||||
void FieldSetDisabledChanged(bool aNotify) override;
|
||||
void SaveState() override;
|
||||
void UpdateValidityElementStates(bool aNotify) final;
|
||||
void UpdateValidityElementStates(bool aNotify);
|
||||
|
||||
void UpdateFormOwner();
|
||||
|
||||
|
|
|
@ -121,7 +121,6 @@ HTMLFormElement::HTMLFormElement(
|
|||
mDeferSubmission(false),
|
||||
mNotifiedObservers(false),
|
||||
mNotifiedObserversResult(false),
|
||||
mEverTriedInvalidSubmit(false),
|
||||
mIsConstructingEntryList(false),
|
||||
mIsFiringSubmissionEvents(false) {
|
||||
// We start out valid.
|
||||
|
@ -261,16 +260,28 @@ void HTMLFormElement::MaybeSubmit(Element* aSubmitter) {
|
|||
return;
|
||||
}
|
||||
|
||||
// 6.1. If form's firing submission events is true, then return.
|
||||
// 5.1. If form's firing submission events is true, then return.
|
||||
if (mIsFiringSubmissionEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 6.2. Set form's firing submission events to true.
|
||||
// 5.2. Set form's firing submission events to true.
|
||||
AutoRestore<bool> resetFiringSubmissionEventsFlag(mIsFiringSubmissionEvents);
|
||||
mIsFiringSubmissionEvents = true;
|
||||
|
||||
// 6.3. If the submitter element's no-validate state is false, then
|
||||
// Flag elements as user-interacted.
|
||||
// FIXME: Should be specified, see:
|
||||
// https://github.com/whatwg/html/issues/10066
|
||||
{
|
||||
for (nsGenericHTMLFormElement* el : mControls->mElements) {
|
||||
el->SetUserInteracted(true);
|
||||
}
|
||||
for (nsGenericHTMLFormElement* el : mControls->mNotInElements) {
|
||||
el->SetUserInteracted(true);
|
||||
}
|
||||
}
|
||||
|
||||
// 5.3. If the submitter element's no-validate state is false, then
|
||||
// interactively validate the constraints of form and examine the result.
|
||||
// If the result is negative (i.e., the constraint validation concluded
|
||||
// that there were invalid fields and probably informed the user of this)
|
||||
|
@ -635,7 +646,6 @@ nsresult HTMLFormElement::DoReset() {
|
|||
doc->FlushPendingNotifications(FlushType::ContentAndNotify);
|
||||
}
|
||||
|
||||
mEverTriedInvalidSubmit = false;
|
||||
// JBK walk the elements[] array instead of form frame controls - bug 34297
|
||||
uint32_t numElements = mControls->Length();
|
||||
for (uint32_t elementX = 0; elementX < numElements; ++elementX) {
|
||||
|
@ -1051,15 +1061,11 @@ nsresult HTMLFormElement::ConstructEntryList(FormData* aFormData) {
|
|||
nsresult rv = mControls->GetSortedControls(sortedControls);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint32_t len = sortedControls.Length();
|
||||
|
||||
//
|
||||
// Walk the list of nodes and call SubmitNamesValues() on the controls
|
||||
//
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
for (nsGenericHTMLFormElement* control : sortedControls) {
|
||||
// Disabled elements don't submit
|
||||
if (!sortedControls[i]->IsDisabled()) {
|
||||
nsCOMPtr<nsIFormControl> fc = do_QueryInterface(sortedControls[i]);
|
||||
if (!control->IsDisabled()) {
|
||||
nsCOMPtr<nsIFormControl> fc = do_QueryInterface(control);
|
||||
MOZ_ASSERT(fc);
|
||||
// Tell the control to submit its name/value pairs to the submission
|
||||
fc->SubmitNamesValues(aFormData);
|
||||
|
@ -1768,44 +1774,6 @@ bool HTMLFormElement::CheckValidFormSubmission() {
|
|||
return true;
|
||||
}
|
||||
|
||||
// For the first invalid submission, we should update element states.
|
||||
// We have to do that _before_ calling the observers so we are sure they
|
||||
// will not interfere (like focusing the element).
|
||||
if (!mEverTriedInvalidSubmit) {
|
||||
mEverTriedInvalidSubmit = true;
|
||||
|
||||
/*
|
||||
* We are going to call update states assuming elements want to
|
||||
* be notified because we can't know.
|
||||
* Submissions shouldn't happen during parsing so it _should_ be safe.
|
||||
*/
|
||||
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
for (nsGenericHTMLFormElement* element : mControls->mElements) {
|
||||
// Input elements can trigger a form submission and we want to
|
||||
// update the style in that case.
|
||||
if (auto* input = HTMLInputElement::FromNode(*element)) {
|
||||
// We don't use nsContentUtils::IsFocusedContent here, because it
|
||||
// doesn't really do what we want for number controls: it's true
|
||||
// for the anonymous textnode inside, but not the number control
|
||||
// itself. We can use the focus state, though, because that gets
|
||||
// synced to the number control by the anonymous text control.
|
||||
if (input->State().HasState(ElementState::FOCUS)) {
|
||||
input->UpdateValidityUIBits(true);
|
||||
}
|
||||
}
|
||||
element->UpdateValidityElementStates(true);
|
||||
}
|
||||
|
||||
// Because of backward compatibility, <input type='image'> is not in
|
||||
// elements but can be invalid.
|
||||
// TODO: should probably be removed when bug 606491 will be fixed.
|
||||
for (nsGenericHTMLFormElement* element : mControls->mNotInElements) {
|
||||
element->UpdateValidityElementStates(true);
|
||||
}
|
||||
}
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
if (!jsapi.Init(GetOwnerGlobal())) {
|
||||
return false;
|
||||
|
|
|
@ -233,16 +233,7 @@ class HTMLFormElement final : public nsGenericHTMLElement,
|
|||
* @param aFormData the form data object
|
||||
*/
|
||||
// TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult ConstructEntryList(FormData* aFormData);
|
||||
|
||||
/**
|
||||
* Whether the submission of this form has been ever prevented because of
|
||||
* being invalid.
|
||||
*
|
||||
* @return Whether the submission of this form has been prevented because of
|
||||
* being invalid.
|
||||
*/
|
||||
bool HasEverTriedInvalidSubmit() const { return mEverTriedInvalidSubmit; }
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult ConstructEntryList(FormData*);
|
||||
|
||||
/**
|
||||
* Implements form[name]. Returns form controls in this form with the correct
|
||||
|
|
|
@ -248,7 +248,7 @@ class DispatchChangeEventCallback final : public GetFilesCallback {
|
|||
RefPtr<HTMLInputElement> inputElement(mInputElement);
|
||||
nsresult rv = nsContentUtils::DispatchInputEvent(inputElement);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to dispatch input event");
|
||||
|
||||
mInputElement->SetUserInteracted(true);
|
||||
rv = nsContentUtils::DispatchTrustedEvent(mInputElement->OwnerDoc(),
|
||||
mInputElement, u"change"_ns,
|
||||
CanBubble::eYes, Cancelable::eNo);
|
||||
|
@ -667,6 +667,7 @@ nsColorPickerShownCallback::Done(const nsAString& aColor) {
|
|||
}
|
||||
|
||||
if (mValueChanged) {
|
||||
mInput->SetUserInteracted(true);
|
||||
rv = nsContentUtils::DispatchTrustedEvent(
|
||||
mInput->OwnerDoc(), static_cast<Element*>(mInput.get()), u"change"_ns,
|
||||
CanBubble::eYes, Cancelable::eNo);
|
||||
|
@ -995,6 +996,7 @@ HTMLInputElement::HTMLInputElement(already_AddRefed<dom::NodeInfo>&& aNodeInfo,
|
|||
mAutocompleteInfoState(nsContentUtils::eAutocompleteAttrState_Unknown),
|
||||
mDisabledChanged(false),
|
||||
mValueChanged(false),
|
||||
mUserInteracted(false),
|
||||
mLastValueChangeWasInteractive(false),
|
||||
mCheckedChanged(false),
|
||||
mChecked(false),
|
||||
|
@ -1006,8 +1008,6 @@ HTMLInputElement::HTMLInputElement(already_AddRefed<dom::NodeInfo>&& aNodeInfo,
|
|||
mCheckedIsToggled(false),
|
||||
mIndeterminate(false),
|
||||
mInhibitRestoration(aFromParser & FROM_PARSER_FRAGMENT),
|
||||
mCanShowValidUI(true),
|
||||
mCanShowInvalidUI(true),
|
||||
mHasRange(false),
|
||||
mIsDraggingRange(false),
|
||||
mNumberControlSpinnerIsSpinning(false),
|
||||
|
@ -2613,15 +2613,25 @@ void HTMLInputElement::AfterSetFilesOrDirectories(bool aSetValueChanged) {
|
|||
}
|
||||
|
||||
void HTMLInputElement::FireChangeEventIfNeeded() {
|
||||
if (!MayFireChangeOnBlur()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We're not exposing the GetValue return value anywhere here, so it's safe to
|
||||
// claim to be a system caller.
|
||||
nsAutoString value;
|
||||
GetValue(value, CallerType::System);
|
||||
|
||||
if (!MayFireChangeOnBlur() || mFocusedValue.Equals(value)) {
|
||||
// NOTE(emilio): Per spec we should not set this if we don't fire the change
|
||||
// event, but that seems like a bug. Using mValueChanged seems reasonable to
|
||||
// keep the expected behavior while
|
||||
// https://github.com/whatwg/html/issues/10013 is resolved.
|
||||
if (mValueChanged) {
|
||||
SetUserInteracted(true);
|
||||
}
|
||||
if (mFocusedValue.Equals(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dispatch the change event.
|
||||
mFocusedValue = value;
|
||||
nsContentUtils::DispatchTrustedEvent(
|
||||
|
@ -3146,9 +3156,9 @@ bool HTMLInputElement::CheckActivationBehaviorPreconditions(
|
|||
// we're a DOMActivate dispatched from click handling, it will not be set.
|
||||
WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
|
||||
bool outerActivateEvent =
|
||||
((mouseEvent && mouseEvent->IsLeftClickEvent()) ||
|
||||
(aVisitor.mEvent->mMessage == eLegacyDOMActivate &&
|
||||
!mInInternalActivate));
|
||||
(mouseEvent && mouseEvent->IsLeftClickEvent()) ||
|
||||
(aVisitor.mEvent->mMessage == eLegacyDOMActivate &&
|
||||
!mInInternalActivate);
|
||||
if (outerActivateEvent) {
|
||||
aVisitor.mItemFlags |= NS_OUTER_ACTIVATE_EVENT;
|
||||
}
|
||||
|
@ -3505,11 +3515,9 @@ void HTMLInputElement::StepNumberControlForUserEvent(int32_t aDirection) {
|
|||
// the user. (IsValid() can return false if the 'required' attribute is
|
||||
// set and the value is the empty string.)
|
||||
if (!IsValueEmpty()) {
|
||||
// We pass 'true' for UpdateValidityUIBits' aIsFocused argument
|
||||
// regardless because we need the UI to update _now_ or the user will
|
||||
// wonder why the step behavior isn't functioning.
|
||||
UpdateValidityUIBits(true);
|
||||
UpdateValidityElementStates(true);
|
||||
// We pass 'true' for SetUserInteracted because we need the UI to update
|
||||
// _now_ or the user will wonder why the step behavior isn't functioning.
|
||||
SetUserInteracted(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -3664,18 +3672,12 @@ static bool ActivatesWithKeyboard(FormControlType aType, uint32_t aKeyCode) {
|
|||
}
|
||||
|
||||
nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
if (aVisitor.mEvent->mMessage == eFocus ||
|
||||
aVisitor.mEvent->mMessage == eBlur) {
|
||||
if (aVisitor.mEvent->mMessage == eBlur) {
|
||||
if (mIsDraggingRange) {
|
||||
FinishRangeThumbDrag();
|
||||
} else if (mNumberControlSpinnerIsSpinning) {
|
||||
StopNumberControlSpinnerSpin();
|
||||
}
|
||||
if (aVisitor.mEvent->mMessage == eBlur) {
|
||||
if (mIsDraggingRange) {
|
||||
FinishRangeThumbDrag();
|
||||
} else if (mNumberControlSpinnerIsSpinning) {
|
||||
StopNumberControlSpinnerSpin();
|
||||
}
|
||||
|
||||
UpdateValidityUIBits(aVisitor.mEvent->mMessage == eFocus);
|
||||
UpdateValidityElementStates(true);
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -4076,11 +4078,14 @@ void HTMLInputElement::ActivationBehavior(EventChainPostVisitor& aVisitor) {
|
|||
}
|
||||
|
||||
if (mCheckedIsToggled) {
|
||||
SetUserInteracted(true);
|
||||
|
||||
// Fire input event and then change event.
|
||||
DebugOnly<nsresult> rvIgnored = nsContentUtils::DispatchInputEvent(this);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
|
||||
"Failed to dispatch input event");
|
||||
|
||||
// FIXME: Why is this different than every other change event?
|
||||
nsContentUtils::DispatchTrustedEvent<WidgetEvent>(
|
||||
OwnerDoc(), static_cast<Element*>(this), eFormChange, CanBubble::eYes,
|
||||
Cancelable::eNo);
|
||||
|
@ -4094,8 +4099,7 @@ void HTMLInputElement::ActivationBehavior(EventChainPostVisitor& aVisitor) {
|
|||
FireEventForAccessibility(this, eFormRadioStateChange);
|
||||
// Fire event for the previous selected radio.
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aVisitor.mItemData);
|
||||
if (HTMLInputElement* previous =
|
||||
HTMLInputElement::FromNodeOrNull(content)) {
|
||||
if (auto* previous = HTMLInputElement::FromNodeOrNull(content)) {
|
||||
FireEventForAccessibility(previous, eFormRadioStateChange);
|
||||
}
|
||||
}
|
||||
|
@ -5927,6 +5931,7 @@ HTMLInputElement::Reset() {
|
|||
SetCheckedChanged(false);
|
||||
SetValueChanged(false);
|
||||
SetLastValueChangeWasInteractive(false);
|
||||
SetUserInteracted(false);
|
||||
|
||||
switch (GetValueMode()) {
|
||||
case VALUE_MODE_VALUE: {
|
||||
|
@ -6222,25 +6227,15 @@ void HTMLInputElement::UpdateValidityElementStates(bool aNotify) {
|
|||
ElementState state;
|
||||
if (IsValid()) {
|
||||
state |= ElementState::VALID;
|
||||
if (mUserInteracted) {
|
||||
state |= ElementState::USER_VALID;
|
||||
}
|
||||
} else {
|
||||
state |= ElementState::INVALID;
|
||||
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) ||
|
||||
(mCanShowInvalidUI && ShouldShowValidityUI())) {
|
||||
if (mUserInteracted) {
|
||||
state |= ElementState::USER_INVALID;
|
||||
}
|
||||
}
|
||||
// :-moz-ui-valid applies if all of the following conditions are true:
|
||||
// 1. The element is not focused, or had either :-moz-ui-valid or
|
||||
// :-moz-ui-invalid applying before it was focused ;
|
||||
// 2. The element is either valid or isn't allowed to have
|
||||
// :-moz-ui-invalid applying ;
|
||||
// 3. The element has already been modified or the user tried to submit the
|
||||
// form owner while invalid.
|
||||
if (mCanShowValidUI && ShouldShowValidityUI() &&
|
||||
(IsValid() ||
|
||||
(!state.HasState(ElementState::USER_INVALID) && !mCanShowInvalidUI))) {
|
||||
state |= ElementState::USER_VALID;
|
||||
}
|
||||
AddStatesSilently(state);
|
||||
}
|
||||
|
||||
|
@ -7251,19 +7246,12 @@ Decimal HTMLInputElement::GetDefaultStep() const {
|
|||
}
|
||||
}
|
||||
|
||||
void HTMLInputElement::UpdateValidityUIBits(bool aIsFocused) {
|
||||
if (aIsFocused) {
|
||||
// If the invalid UI is shown, we should show it while focusing (and
|
||||
// update). Otherwise, we should not.
|
||||
mCanShowInvalidUI = !IsValid() && ShouldShowValidityUI();
|
||||
|
||||
// If neither invalid UI nor valid UI is shown, we shouldn't show the valid
|
||||
// UI while typing.
|
||||
mCanShowValidUI = ShouldShowValidityUI();
|
||||
} else {
|
||||
mCanShowInvalidUI = true;
|
||||
mCanShowValidUI = true;
|
||||
void HTMLInputElement::SetUserInteracted(bool aInteracted) {
|
||||
if (mUserInteracted == aInteracted) {
|
||||
return;
|
||||
}
|
||||
mUserInteracted = aInteracted;
|
||||
UpdateValidityElementStates(true);
|
||||
}
|
||||
|
||||
void HTMLInputElement::UpdateInRange(bool aNotify) {
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Variant.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/HTMLFormElement.h" // for HasEverTriedInvalidSubmit()
|
||||
#include "mozilla/dom/HTMLInputElementBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
|
@ -36,6 +35,7 @@
|
|||
#include "nsIContentPrefService2.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
class nsIEditor;
|
||||
class nsIRadioVisitor;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -338,7 +338,7 @@ class HTMLInputElement final : public TextControlElement,
|
|||
// as needed. aNotify controls whether the element state update
|
||||
// needs to notify.
|
||||
void UpdateAllValidityStates(bool aNotify);
|
||||
void UpdateValidityElementStates(bool aNotify) final;
|
||||
void UpdateValidityElementStates(bool aNotify);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void MaybeUpdateAllValidityStates(bool aNotify) {
|
||||
// If you need to add new type which supports validationMessage, you should
|
||||
|
@ -395,16 +395,7 @@ class HTMLInputElement final : public TextControlElement,
|
|||
*/
|
||||
void SetFilePickerFiltersFromAccept(nsIFilePicker* filePicker);
|
||||
|
||||
/**
|
||||
* The form might need to request an update of the UI bits
|
||||
* (BF_CAN_SHOW_INVALID_UI and BF_CAN_SHOW_VALID_UI) when an invalid form
|
||||
* submission is tried.
|
||||
*
|
||||
* @param aIsFocused Whether the element is currently focused.
|
||||
*
|
||||
* @note The caller is responsible to call ContentStatesChanged.
|
||||
*/
|
||||
void UpdateValidityUIBits(bool aIsFocused);
|
||||
void SetUserInteracted(bool) final;
|
||||
|
||||
/**
|
||||
* Fires change event if mFocusedValue and current value held are unequal and
|
||||
|
@ -1115,37 +1106,6 @@ class HTMLInputElement final : public TextControlElement,
|
|||
void SetAutoDirectionality(bool aNotify,
|
||||
const nsAString* aKnownValue = nullptr);
|
||||
|
||||
/**
|
||||
* Return if an element should have a specific validity UI
|
||||
* (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes).
|
||||
*
|
||||
* @return Whether the element should have a validity UI.
|
||||
*/
|
||||
bool ShouldShowValidityUI() const {
|
||||
/**
|
||||
* Always show the validity UI if the form has already tried to be submitted
|
||||
* but was invalid.
|
||||
*
|
||||
* Otherwise, show the validity UI if the element's value has been changed.
|
||||
*/
|
||||
if (mForm && mForm->HasEverTriedInvalidSubmit()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (GetValueMode()) {
|
||||
case VALUE_MODE_DEFAULT:
|
||||
return true;
|
||||
case VALUE_MODE_DEFAULT_ON:
|
||||
return GetCheckedChanged();
|
||||
case VALUE_MODE_VALUE:
|
||||
case VALUE_MODE_FILENAME:
|
||||
return mValueChanged;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("We should not be there: there are no other modes.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the radio group container within the DOM tree that the element
|
||||
* is currently a member of, if one exists.
|
||||
|
@ -1551,6 +1511,8 @@ class HTMLInputElement final : public TextControlElement,
|
|||
// https://html.spec.whatwg.org/#concept-fe-dirty
|
||||
// TODO: Maybe rename to match the spec?
|
||||
bool mValueChanged : 1;
|
||||
// https://html.spec.whatwg.org/#user-interacted
|
||||
bool mUserInteracted : 1;
|
||||
bool mLastValueChangeWasInteractive : 1;
|
||||
bool mCheckedChanged : 1;
|
||||
bool mChecked : 1;
|
||||
|
@ -1561,8 +1523,6 @@ class HTMLInputElement final : public TextControlElement,
|
|||
bool mCheckedIsToggled : 1;
|
||||
bool mIndeterminate : 1;
|
||||
bool mInhibitRestoration : 1;
|
||||
bool mCanShowValidUI : 1;
|
||||
bool mCanShowInvalidUI : 1;
|
||||
bool mHasRange : 1;
|
||||
bool mIsDraggingRange : 1;
|
||||
bool mNumberControlSpinnerIsSpinning : 1;
|
||||
|
|
|
@ -119,10 +119,8 @@ HTMLSelectElement::HTMLSelectElement(
|
|||
mDisabledChanged(false),
|
||||
mMutating(false),
|
||||
mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)),
|
||||
mSelectionHasChanged(false),
|
||||
mUserInteracted(false),
|
||||
mDefaultSelectionSet(false),
|
||||
mCanShowInvalidUI(true),
|
||||
mCanShowValidUI(true),
|
||||
mIsOpenInParentProcess(false),
|
||||
mNonOptionChildren(0),
|
||||
mOptGroupCount(0),
|
||||
|
@ -282,7 +280,7 @@ void HTMLSelectElement::InsertOptionsIntoList(nsIContent* aOptions,
|
|||
// Fix the currently selected index
|
||||
if (aListIndex <= mSelectedIndex) {
|
||||
mSelectedIndex += (insertIndex - aListIndex);
|
||||
SetSelectionChanged(true, aNotify);
|
||||
OnSelectionChanged();
|
||||
}
|
||||
|
||||
// Get the frame stuff for notification. No need to flush here
|
||||
|
@ -382,7 +380,7 @@ nsresult HTMLSelectElement::RemoveOptionsFromList(nsIContent* aOptions,
|
|||
// If this is a Combobox, no other Item will be selected.
|
||||
if (IsCombobox()) {
|
||||
mSelectedIndex = -1;
|
||||
SetSelectionChanged(true, aNotify);
|
||||
OnSelectionChanged();
|
||||
} else {
|
||||
FindSelectedIndex(aListIndex, aNotify);
|
||||
}
|
||||
|
@ -390,7 +388,7 @@ nsresult HTMLSelectElement::RemoveOptionsFromList(nsIContent* aOptions,
|
|||
// Shift the selected index if something in front of it was removed
|
||||
// aListIndex+numRemoved <= mSelectedIndex
|
||||
mSelectedIndex -= numRemoved;
|
||||
SetSelectionChanged(true, aNotify);
|
||||
OnSelectionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -701,7 +699,7 @@ void HTMLSelectElement::SetSelectedIndexInternal(int32_t aIndex, bool aNotify) {
|
|||
selectFrame->OnSetSelectedIndex(oldSelectedIndex, mSelectedIndex);
|
||||
}
|
||||
|
||||
SetSelectionChanged(true, aNotify);
|
||||
OnSelectionChanged();
|
||||
}
|
||||
|
||||
bool HTMLSelectElement::IsOptionSelectedByIndex(int32_t aIndex) const {
|
||||
|
@ -716,7 +714,7 @@ void HTMLSelectElement::OnOptionSelected(nsISelectControlFrame* aSelectFrame,
|
|||
// Set the selected index
|
||||
if (aSelected && (aIndex < mSelectedIndex || mSelectedIndex < 0)) {
|
||||
mSelectedIndex = aIndex;
|
||||
SetSelectionChanged(true, aNotify);
|
||||
OnSelectionChanged();
|
||||
} else if (!aSelected && aIndex == mSelectedIndex) {
|
||||
FindSelectedIndex(aIndex + 1, aNotify);
|
||||
}
|
||||
|
@ -741,15 +739,14 @@ void HTMLSelectElement::OnOptionSelected(nsISelectControlFrame* aSelectFrame,
|
|||
|
||||
void HTMLSelectElement::FindSelectedIndex(int32_t aStartIndex, bool aNotify) {
|
||||
mSelectedIndex = -1;
|
||||
SetSelectionChanged(true, aNotify);
|
||||
uint32_t len = Length();
|
||||
for (int32_t i = aStartIndex; i < int32_t(len); i++) {
|
||||
if (IsOptionSelectedByIndex(i)) {
|
||||
mSelectedIndex = i;
|
||||
SetSelectionChanged(true, aNotify);
|
||||
break;
|
||||
}
|
||||
}
|
||||
OnSelectionChanged();
|
||||
}
|
||||
|
||||
// XXX Consider splitting this into two functions for ease of reading:
|
||||
|
@ -1270,27 +1267,6 @@ void HTMLSelectElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
|||
nsGenericHTMLFormControlElementWithState::GetEventTargetParent(aVisitor);
|
||||
}
|
||||
|
||||
nsresult HTMLSelectElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
if (aVisitor.mEvent->mMessage == eFocus) {
|
||||
// If the invalid UI is shown, we should show it while focused and
|
||||
// update the invalid/valid UI.
|
||||
mCanShowInvalidUI = !IsValid() && ShouldShowValidityUI();
|
||||
|
||||
// If neither invalid UI nor valid UI is shown, we shouldn't show the valid
|
||||
// UI while focused.
|
||||
mCanShowValidUI = ShouldShowValidityUI();
|
||||
|
||||
// We don't have to update ElementState::USER_INVALID nor
|
||||
// ElementState::USER_VALID given that the states should not change.
|
||||
} else if (aVisitor.mEvent->mMessage == eBlur) {
|
||||
mCanShowInvalidUI = true;
|
||||
mCanShowValidUI = true;
|
||||
UpdateValidityElementStates(true);
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormControlElementWithState::PostHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
void HTMLSelectElement::UpdateValidityElementStates(bool aNotify) {
|
||||
AutoStateChangeNotifier notifier(*this, aNotify);
|
||||
RemoveStatesSilently(ElementState::VALIDITY_STATES);
|
||||
|
@ -1301,28 +1277,16 @@ void HTMLSelectElement::UpdateValidityElementStates(bool aNotify) {
|
|||
ElementState state;
|
||||
if (IsValid()) {
|
||||
state |= ElementState::VALID;
|
||||
if (mUserInteracted) {
|
||||
state |= ElementState::USER_VALID;
|
||||
}
|
||||
} else {
|
||||
state |= ElementState::INVALID;
|
||||
|
||||
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) ||
|
||||
(mCanShowInvalidUI && ShouldShowValidityUI())) {
|
||||
if (mUserInteracted) {
|
||||
state |= ElementState::USER_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
// :-moz-ui-valid applies if all the following are true:
|
||||
// 1. The element is not focused, or had either :-moz-ui-valid or
|
||||
// :-moz-ui-invalid applying before it was focused ;
|
||||
// 2. The element is either valid or isn't allowed to have
|
||||
// :-moz-ui-invalid applying ;
|
||||
// 3. The element has already been modified or the user tried to submit the
|
||||
// form owner while invalid.
|
||||
if (mCanShowValidUI && ShouldShowValidityUI() &&
|
||||
(IsValid() ||
|
||||
(state.HasState(ElementState::USER_INVALID) && !mCanShowInvalidUI))) {
|
||||
state |= ElementState::USER_VALID;
|
||||
}
|
||||
|
||||
AddStatesSilently(state);
|
||||
}
|
||||
|
||||
|
@ -1453,9 +1417,9 @@ HTMLSelectElement::Reset() {
|
|||
SelectSomething(true);
|
||||
}
|
||||
|
||||
SetSelectionChanged(false, true);
|
||||
OnSelectionChanged();
|
||||
SetUserInteracted(false);
|
||||
|
||||
//
|
||||
// Let the frame know we were reset
|
||||
//
|
||||
// Don't flush, if there's no frame yet it won't care about us being
|
||||
|
@ -1626,18 +1590,11 @@ void HTMLSelectElement::FieldSetDisabledChanged(bool aNotify) {
|
|||
UpdateValidityElementStates(aNotify);
|
||||
}
|
||||
|
||||
void HTMLSelectElement::SetSelectionChanged(bool aValue, bool aNotify) {
|
||||
void HTMLSelectElement::OnSelectionChanged() {
|
||||
if (!mDefaultSelectionSet) {
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateSelectedOptions();
|
||||
|
||||
bool previousSelectionChangedValue = mSelectionHasChanged;
|
||||
mSelectionHasChanged = aValue;
|
||||
if (mSelectionHasChanged != previousSelectionChangedValue) {
|
||||
UpdateValidityElementStates(aNotify);
|
||||
}
|
||||
}
|
||||
|
||||
void HTMLSelectElement::UpdateSelectedOptions() {
|
||||
|
@ -1646,6 +1603,14 @@ void HTMLSelectElement::UpdateSelectedOptions() {
|
|||
}
|
||||
}
|
||||
|
||||
void HTMLSelectElement::SetUserInteracted(bool aInteracted) {
|
||||
if (mUserInteracted == aInteracted) {
|
||||
return;
|
||||
}
|
||||
mUserInteracted = aInteracted;
|
||||
UpdateValidityElementStates(true);
|
||||
}
|
||||
|
||||
void HTMLSelectElement::SetPreviewValue(const nsAString& aValue) {
|
||||
mPreviewValue = aValue;
|
||||
nsContentUtils::RemoveNewlines(mPreviewValue);
|
||||
|
@ -1656,6 +1621,22 @@ void HTMLSelectElement::SetPreviewValue(const nsAString& aValue) {
|
|||
}
|
||||
}
|
||||
|
||||
void HTMLSelectElement::UserFinishedInteracting(bool aChanged) {
|
||||
SetUserInteracted(true);
|
||||
if (!aChanged) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dispatch the input event.
|
||||
DebugOnly<nsresult> rvIgnored = nsContentUtils::DispatchInputEvent(this);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
|
||||
"Failed to dispatch input event");
|
||||
|
||||
// Dispatch the change event.
|
||||
nsContentUtils::DispatchTrustedEvent(OwnerDoc(), this, u"change"_ns,
|
||||
CanBubble::eYes, Cancelable::eNo);
|
||||
}
|
||||
|
||||
JSObject* HTMLSelectElement::WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
return HTMLSelectElement_Binding::Wrap(aCx, this, aGivenProto);
|
||||
|
|
|
@ -128,6 +128,9 @@ class HTMLSelectElement final : public nsGenericHTMLFormControlElementWithState,
|
|||
|
||||
void GetAutocompleteInfo(AutocompleteInfo& aInfo);
|
||||
|
||||
// Sets the user interacted flag and fires input/change events if needed.
|
||||
MOZ_CAN_RUN_SCRIPT void UserFinishedInteracting(bool aChanged);
|
||||
|
||||
bool Disabled() const { return GetBoolAttr(nsGkAtoms::disabled); }
|
||||
void SetDisabled(bool aVal, ErrorResult& aRv) {
|
||||
SetHTMLBoolAttr(nsGkAtoms::disabled, aVal, aRv);
|
||||
|
@ -194,8 +197,6 @@ class HTMLSelectElement final : public nsGenericHTMLFormControlElementWithState,
|
|||
|
||||
// nsIContent
|
||||
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
|
||||
|
||||
bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
|
||||
int32_t* aTabIndex) override;
|
||||
|
@ -300,7 +301,7 @@ class HTMLSelectElement final : public nsGenericHTMLFormControlElementWithState,
|
|||
ValidityStateType aType) override;
|
||||
|
||||
void UpdateValueMissingValidityState();
|
||||
void UpdateValidityElementStates(bool aNotify) final;
|
||||
void UpdateValidityElementStates(bool aNotify);
|
||||
/**
|
||||
* Insert aElement before the node given by aBefore
|
||||
*/
|
||||
|
@ -451,7 +452,7 @@ class HTMLSelectElement final : public nsGenericHTMLFormControlElementWithState,
|
|||
|
||||
void SetSelectedIndexInternal(int32_t aIndex, bool aNotify);
|
||||
|
||||
void SetSelectionChanged(bool aValue, bool aNotify);
|
||||
void OnSelectionChanged();
|
||||
|
||||
/**
|
||||
* Marks the selectedOptions list as dirty, so that it'll populate itself
|
||||
|
@ -459,25 +460,7 @@ class HTMLSelectElement final : public nsGenericHTMLFormControlElementWithState,
|
|||
*/
|
||||
void UpdateSelectedOptions();
|
||||
|
||||
/**
|
||||
* Return whether an element should have a validity UI.
|
||||
* (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes).
|
||||
*
|
||||
* @return Whether the element should have a validity UI.
|
||||
*/
|
||||
bool ShouldShowValidityUI() const {
|
||||
/**
|
||||
* Always show the validity UI if the form has already tried to be submitted
|
||||
* but was invalid.
|
||||
*
|
||||
* Otherwise, show the validity UI if the selection has been changed.
|
||||
*/
|
||||
if (mForm && mForm->HasEverTriedInvalidSubmit()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return mSelectionHasChanged;
|
||||
}
|
||||
void SetUserInteracted(bool) final;
|
||||
|
||||
/** The options[] array */
|
||||
RefPtr<HTMLOptionsCollection> mOptions;
|
||||
|
@ -495,23 +478,10 @@ class HTMLSelectElement final : public nsGenericHTMLFormControlElementWithState,
|
|||
* True if DoneAddingChildren will get called but shouldn't restore state.
|
||||
*/
|
||||
bool mInhibitStateRestoration : 1;
|
||||
/**
|
||||
* True if the selection has changed since the element's creation.
|
||||
*/
|
||||
bool mSelectionHasChanged : 1;
|
||||
/**
|
||||
* True if the default selected option has been set.
|
||||
*/
|
||||
/** https://html.spec.whatwg.org/#user-interacted */
|
||||
bool mUserInteracted : 1;
|
||||
/** True if the default selected option has been set. */
|
||||
bool mDefaultSelectionSet : 1;
|
||||
/**
|
||||
* True if :-moz-ui-invalid can be shown.
|
||||
*/
|
||||
bool mCanShowInvalidUI : 1;
|
||||
/**
|
||||
* True if :-moz-ui-valid can be shown.
|
||||
*/
|
||||
bool mCanShowValidUI : 1;
|
||||
|
||||
/** True if we're open in the parent process */
|
||||
bool mIsOpenInParentProcess : 1;
|
||||
|
||||
|
|
|
@ -48,15 +48,8 @@ HTMLTextAreaElement::HTMLTextAreaElement(
|
|||
FromParser aFromParser)
|
||||
: TextControlElement(std::move(aNodeInfo), aFromParser,
|
||||
FormControlType::Textarea),
|
||||
mValueChanged(false),
|
||||
mLastValueChangeWasInteractive(false),
|
||||
mHandlingSelect(false),
|
||||
mDoneAddingChildren(!aFromParser),
|
||||
mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)),
|
||||
mDisabledChanged(false),
|
||||
mCanShowInvalidUI(true),
|
||||
mCanShowValidUI(true),
|
||||
mIsPreviewEnabled(false),
|
||||
mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown),
|
||||
mState(TextControlState::Construct(this)) {
|
||||
AddMutationObserver(this);
|
||||
|
@ -465,6 +458,13 @@ void HTMLTextAreaElement::FireChangeEventIfNeeded() {
|
|||
nsString value;
|
||||
GetValueInternal(value, true);
|
||||
|
||||
// NOTE(emilio): This is not quite on the spec, but matches <input>, see
|
||||
// https://github.com/whatwg/html/issues/10011 and
|
||||
// https://github.com/whatwg/html/issues/10013
|
||||
if (mValueChanged) {
|
||||
SetUserInteracted(true);
|
||||
}
|
||||
|
||||
if (mFocusedValue.Equals(value)) {
|
||||
return;
|
||||
}
|
||||
|
@ -480,24 +480,6 @@ nsresult HTMLTextAreaElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
|||
mHandlingSelect = false;
|
||||
}
|
||||
|
||||
if (aVisitor.mEvent->mMessage == eFocus ||
|
||||
aVisitor.mEvent->mMessage == eBlur) {
|
||||
if (aVisitor.mEvent->mMessage == eFocus) {
|
||||
// If the invalid UI is shown, we should show it while focusing (and
|
||||
// update). Otherwise, we should not.
|
||||
GetValueInternal(mFocusedValue, true);
|
||||
mCanShowInvalidUI = !IsValid() && ShouldShowValidityUI();
|
||||
|
||||
// If neither invalid UI nor valid UI is shown, we shouldn't show the
|
||||
// valid UI while typing.
|
||||
mCanShowValidUI = ShouldShowValidityUI();
|
||||
} else { // eBlur
|
||||
mCanShowInvalidUI = true;
|
||||
mCanShowValidUI = true;
|
||||
}
|
||||
UpdateValidityElementStates(true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -654,6 +636,7 @@ nsresult HTMLTextAreaElement::Reset() {
|
|||
nsAutoString resetVal;
|
||||
GetDefaultValue(resetVal, IgnoreErrors());
|
||||
SetValueChanged(false);
|
||||
SetUserInteracted(false);
|
||||
|
||||
nsresult rv = SetValueInternal(resetVal, ValueSetterOption::ByInternalAPI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -751,28 +734,15 @@ void HTMLTextAreaElement::UpdateValidityElementStates(bool aNotify) {
|
|||
ElementState state;
|
||||
if (IsValid()) {
|
||||
state |= ElementState::VALID;
|
||||
if (mUserInteracted) {
|
||||
state |= ElementState::USER_VALID;
|
||||
}
|
||||
} else {
|
||||
state |= ElementState::INVALID;
|
||||
// :-moz-ui-invalid always apply if the element suffers from a custom
|
||||
// error.
|
||||
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) ||
|
||||
(mCanShowInvalidUI && ShouldShowValidityUI())) {
|
||||
if (mUserInteracted) {
|
||||
state |= ElementState::USER_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
// :-moz-ui-valid applies if all the following are true:
|
||||
// 1. The element is not focused, or had either :-moz-ui-valid or
|
||||
// :-moz-ui-invalid applying before it was focused ;
|
||||
// 2. The element is either valid or isn't allowed to have
|
||||
// :-moz-ui-invalid applying ;
|
||||
// 3. The element has already been modified or the user tried to submit the
|
||||
// form owner while invalid.
|
||||
if (mCanShowValidUI && ShouldShowValidityUI() &&
|
||||
(IsValid() ||
|
||||
(state.HasState(ElementState::USER_INVALID) && !mCanShowInvalidUI))) {
|
||||
state |= ElementState::USER_VALID;
|
||||
}
|
||||
AddStatesSilently(state);
|
||||
}
|
||||
|
||||
|
@ -1156,6 +1126,14 @@ bool HTMLTextAreaElement::HasCachedSelection() {
|
|||
return mState->IsSelectionCached();
|
||||
}
|
||||
|
||||
void HTMLTextAreaElement::SetUserInteracted(bool aInteracted) {
|
||||
if (mUserInteracted == aInteracted) {
|
||||
return;
|
||||
}
|
||||
mUserInteracted = aInteracted;
|
||||
UpdateValidityElementStates(true);
|
||||
}
|
||||
|
||||
void HTMLTextAreaElement::FieldSetDisabledChanged(bool aNotify) {
|
||||
// This *has* to be called before UpdateBarredFromConstraintValidation and
|
||||
// UpdateValueMissingValidityState because these two functions depend on our
|
||||
|
|
|
@ -288,25 +288,23 @@ class HTMLTextAreaElement final : public TextControlElement,
|
|||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
nsCOMPtr<nsIControllers> mControllers;
|
||||
/** https://html.spec.whatwg.org/#user-interacted */
|
||||
bool mUserInteracted = false;
|
||||
/** Whether or not the value has changed since its default value was given. */
|
||||
bool mValueChanged;
|
||||
bool mValueChanged = false;
|
||||
/** Whether or not the last change to the value was made interactively by the
|
||||
* user. */
|
||||
bool mLastValueChangeWasInteractive;
|
||||
bool mLastValueChangeWasInteractive = false;
|
||||
/** Whether or not we are already handling select event. */
|
||||
bool mHandlingSelect;
|
||||
bool mHandlingSelect = false;
|
||||
/** Whether or not we are done adding children (always true if not
|
||||
created by a parser */
|
||||
bool mDoneAddingChildren;
|
||||
/** Whether state restoration should be inhibited in DoneAddingChildren. */
|
||||
bool mInhibitStateRestoration;
|
||||
/** Whether our disabled state has changed from the default **/
|
||||
bool mDisabledChanged;
|
||||
/** Whether we should make :-moz-ui-invalid apply on the element. **/
|
||||
bool mCanShowInvalidUI;
|
||||
/** Whether we should make :-moz-ui-valid apply on the element. **/
|
||||
bool mCanShowValidUI;
|
||||
bool mIsPreviewEnabled;
|
||||
bool mDisabledChanged = false;
|
||||
bool mIsPreviewEnabled = false;
|
||||
|
||||
nsContentUtils::AutocompleteAttrState mAutocompleteAttrState;
|
||||
|
||||
|
@ -350,27 +348,6 @@ class HTMLTextAreaElement final : public TextControlElement,
|
|||
void SetDirectionFromValue(bool aNotify,
|
||||
const nsAString* aKnownValue = nullptr);
|
||||
|
||||
/**
|
||||
* Return if an element should have a specific validity UI
|
||||
* (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes).
|
||||
*
|
||||
* @return Whether the element should have a validity UI.
|
||||
*/
|
||||
bool ShouldShowValidityUI() const {
|
||||
/**
|
||||
* Always show the validity UI if the form has already tried to be submitted
|
||||
* but was invalid.
|
||||
*
|
||||
* Otherwise, show the validity UI if the element's value has been changed.
|
||||
*/
|
||||
|
||||
if (mForm && mForm->HasEverTriedInvalidSubmit()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return mValueChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mutable state of the element.
|
||||
*/
|
||||
|
@ -392,7 +369,8 @@ class HTMLTextAreaElement final : public TextControlElement,
|
|||
void GetSelectionRange(uint32_t* aSelectionStart, uint32_t* aSelectionEnd,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void UpdateValidityElementStates(bool aNotify) final;
|
||||
void SetUserInteracted(bool) final;
|
||||
void UpdateValidityElementStates(bool aNotify);
|
||||
|
||||
private:
|
||||
static void MapAttributesIntoRule(MappedDeclarationsBuilder&);
|
||||
|
|
|
@ -1795,7 +1795,6 @@ void nsGenericHTMLFormElement::ClearForm(bool aRemoveFromForm,
|
|||
UnsetFlags(ADDED_TO_FORM);
|
||||
SetFormInternal(nullptr, false);
|
||||
AfterClearForm(aUnbindOrDelete);
|
||||
UpdateValidityElementStates(true);
|
||||
}
|
||||
|
||||
nsresult nsGenericHTMLFormElement::BindToTree(BindContext& aContext,
|
||||
|
@ -2148,11 +2147,6 @@ void nsGenericHTMLFormElement::UpdateFormOwner(bool aBindToTree,
|
|||
form->AddElementToTable(this, idVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (form != oldForm) {
|
||||
// ui-valid / invalid depends on the form for some elements
|
||||
UpdateValidityElementStates(true);
|
||||
}
|
||||
}
|
||||
|
||||
void nsGenericHTMLFormElement::UpdateFieldSet(bool aNotify) {
|
||||
|
|
|
@ -1022,10 +1022,9 @@ class nsGenericHTMLFormElement : public nsGenericHTMLElement {
|
|||
*/
|
||||
already_AddRefed<nsILayoutHistoryState> GetLayoutHistory(bool aRead);
|
||||
|
||||
// Form changes (in particular whether our current form has been submitted
|
||||
// invalidly) affect the user-valid/user-invalid pseudo-classes. Sub-classes
|
||||
// can override this to react to it.
|
||||
virtual void UpdateValidityElementStates(bool aNotify) {}
|
||||
// Sets the user-interacted flag in
|
||||
// https://html.spec.whatwg.org/#user-interacted, if it applies.
|
||||
virtual void SetUserInteracted(bool aNotify) {}
|
||||
|
||||
protected:
|
||||
virtual ~nsGenericHTMLFormElement() = default;
|
||||
|
|
|
@ -83,13 +83,6 @@ bool nsIConstraintValidation::ReportValidity() {
|
|||
event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
|
||||
|
||||
element->DispatchEvent(*event);
|
||||
|
||||
auto* inputElement = HTMLInputElement::FromNode(element);
|
||||
if (inputElement && inputElement->State().HasState(ElementState::FOCUS)) {
|
||||
inputElement->UpdateValidityUIBits(true);
|
||||
inputElement->UpdateValidityElementStates(true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=605124
|
|||
|
||||
function checkPseudoClass(aElement, aExpected)
|
||||
{
|
||||
is(aElement.matches(":-moz-ui-invalid"), aExpected,
|
||||
"matches(':-moz-ui-invalid') should return " + aExpected + " for " + aElement);
|
||||
is(aElement.matches(":user-invalid"), aExpected,
|
||||
"matches(':user-invalid') should return " + aExpected + " for " + aElement);
|
||||
}
|
||||
|
||||
var content = document.getElementById('content');
|
||||
|
@ -62,9 +62,9 @@ checkPseudoClass(select, true);
|
|||
content.appendChild(textarea);
|
||||
content.appendChild(input);
|
||||
content.appendChild(select);
|
||||
checkPseudoClass(textarea, false);
|
||||
checkPseudoClass(input, false);
|
||||
checkPseudoClass(select, false);
|
||||
checkPseudoClass(textarea, true);
|
||||
checkPseudoClass(input, true);
|
||||
checkPseudoClass(select, true);
|
||||
|
||||
// Back in the form.
|
||||
form.appendChild(textarea);
|
||||
|
@ -89,10 +89,9 @@ checkPseudoClass(select, true);
|
|||
|
||||
// Remove the form.
|
||||
document.getElementsByTagName('table')[0].removeChild(form);
|
||||
checkPseudoClass(textarea, false);
|
||||
checkPseudoClass(input, false);
|
||||
checkPseudoClass(select, false);
|
||||
|
||||
checkPseudoClass(textarea, true);
|
||||
checkPseudoClass(input, true);
|
||||
checkPseudoClass(select, true);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -31,15 +31,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=605125
|
|||
|
||||
function checkPseudoClass(aElement, aExpected)
|
||||
{
|
||||
is(aElement.matches(":-moz-ui-valid"), aExpected,
|
||||
"matches(':-moz-ui-valid') should return " + aExpected + " for " + aElement);
|
||||
is(aElement.matches(":user-valid"), aExpected,
|
||||
"matches(':user-valid') should return " + aExpected + " for " + aElement);
|
||||
}
|
||||
|
||||
function checkElement(aElement)
|
||||
{
|
||||
checkPseudoClass(aElement, false);
|
||||
|
||||
// Focusing while :-moz-ui-valid doesn't apply,
|
||||
// Focusing while :user-valid doesn't apply,
|
||||
// the pseudo-class should not apply while typing.
|
||||
aElement.focus();
|
||||
checkPseudoClass(aElement, false);
|
||||
|
@ -57,7 +57,7 @@ function checkElement(aElement)
|
|||
aElement.blur();
|
||||
checkPseudoClass(aElement, true);
|
||||
|
||||
// Focusing while :-moz-ui-valid applies,
|
||||
// Focusing while :user-valid applies,
|
||||
// the pseudo-class should apply while typing if appropriate.
|
||||
aElement.focus();
|
||||
checkPseudoClass(aElement, true);
|
||||
|
@ -76,7 +76,7 @@ function checkElement(aElement)
|
|||
aElement.required = true;
|
||||
checkPseudoClass(aElement, false);
|
||||
|
||||
// Focusing while :-moz-ui-invalid applies,
|
||||
// Focusing while :user-invalid applies,
|
||||
// the pseudo-class should apply while typing if appropriate.
|
||||
aElement.focus();
|
||||
checkPseudoClass(aElement, false);
|
||||
|
@ -96,20 +96,15 @@ function checkSelectElement(aElement)
|
|||
{
|
||||
checkPseudoClass(aElement, false);
|
||||
|
||||
// Focusing while :-moz-ui-valid doesn't apply,
|
||||
// Focusing while :user-valid doesn't apply,
|
||||
// the pseudo-class should not apply while changing selection.
|
||||
aElement.focus();
|
||||
checkPseudoClass(aElement, false);
|
||||
|
||||
aElement.selectedIndex = 1;
|
||||
checkPseudoClass(aElement, false);
|
||||
aElement.selectedIndex = 0;
|
||||
checkPseudoClass(aElement, false);
|
||||
|
||||
aElement.blur();
|
||||
synthesizeKey("KEY_ArrowDown");
|
||||
checkPseudoClass(aElement, true);
|
||||
|
||||
// Focusing while :-moz-ui-valid applies,
|
||||
// Focusing while :user-valid applies,
|
||||
// the pseudo-class should apply while changing selection if appropriate.
|
||||
aElement.focus();
|
||||
checkPseudoClass(aElement, true);
|
||||
|
@ -127,12 +122,12 @@ function checkSelectElement(aElement)
|
|||
}
|
||||
checkPseudoClass(aElement, false);
|
||||
|
||||
// Focusing while :-moz-ui-invalid applies,
|
||||
// Focusing while :user-invalid applies,
|
||||
// the pseudo-class should apply while changing selection if appropriate.
|
||||
aElement.focus();
|
||||
checkPseudoClass(aElement, false);
|
||||
|
||||
aElement.selectedIndex = 1;
|
||||
synthesizeKey("KEY_ArrowDown");
|
||||
checkPseudoClass(aElement, true);
|
||||
aElement.selectedIndex = 0;
|
||||
checkPseudoClass(aElement, aElement.multiple);
|
||||
|
|
|
@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=610687
|
|||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=610687">Mozilla Bug 610687</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<div id="content">
|
||||
<form>
|
||||
<input type='radio' name='a'>
|
||||
<input type='radio' name='a'>
|
||||
|
@ -34,14 +34,14 @@ function checkPseudoClasses(aElement, aValid, aValidUI, aInvalidUI)
|
|||
ok(aElement.matches(":invalid"), ":invalid should apply");
|
||||
}
|
||||
|
||||
is(aElement.matches(":-moz-ui-valid"), aValidUI,
|
||||
aValid ? ":-moz-ui-valid should apply" : ":-moz-ui-valid should not apply");
|
||||
is(aElement.matches(":user-valid"), aValidUI,
|
||||
aValid ? ":user-valid should apply" : ":user-valid should not apply");
|
||||
|
||||
is(aElement.matches(":-moz-ui-invalid"), aInvalidUI,
|
||||
aInvalidUI ? ":-moz-ui-invalid should apply" : ":-moz-ui-invalid should not apply");
|
||||
is(aElement.matches(":user-invalid"), aInvalidUI,
|
||||
aInvalidUI ? ":user-invalid should apply" : ":user-invalid should not apply");
|
||||
|
||||
if (aInvalidUI && (aValid || aValidUI)) {
|
||||
ok(false, ":invalid can't apply with :valid or :-moz-valid-ui");
|
||||
ok(false, ":invalid can't apply with :valid or :user-valid");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,23 +63,17 @@ function checkRadios(r1, r2, r3, form)
|
|||
checkPseudoClasses(r2, false, false, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Suffering from being missing (with ui-invalid).
|
||||
r1.checked = false;
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Do not suffer from being missing (with ui-valid).
|
||||
r1.checked = true;
|
||||
r1.click();
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r2, true, false, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Do not suffer from being missing (with ui-valid).
|
||||
r1.checked = false;
|
||||
r1.required = false;
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r2, true, false, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Suffering from being missing (with ui-invalid) with required set on one radio
|
||||
|
@ -87,35 +81,35 @@ function checkRadios(r1, r2, r3, form)
|
|||
r1.required = true;
|
||||
r2.checked = false;
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Do not suffer from being missing (with ui-valid) by checking the radio which
|
||||
// hasn't the required attribute.
|
||||
r2.checked = true;
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r2, true, false, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// .setCustomValidity() should not affect the entire group.
|
||||
r1.checked = r2.checked = r3.checked = false;
|
||||
r1.checked = false; r2.checked = false; r3.checked = false;
|
||||
r1.required = false;
|
||||
r1.setCustomValidity('foo');
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r3, true, true, false);
|
||||
checkPseudoClasses(r2, true, false, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
r1.setCustomValidity('');
|
||||
r2.setCustomValidity('foo');
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r3, true, true, false);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
r2.setCustomValidity('');
|
||||
r3.setCustomValidity('foo');
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r3, false, false, true);
|
||||
checkPseudoClasses(r2, true, false, false);
|
||||
checkPseudoClasses(r3, false, false, false);
|
||||
|
||||
// Removing the radio with the required attribute should make the group valid.
|
||||
r1.setCustomValidity('');
|
||||
|
@ -124,64 +118,64 @@ function checkRadios(r1, r2, r3, form)
|
|||
r2.required = true;
|
||||
r1.checked = r2.checked = false;
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
var p = r2.parentNode;
|
||||
p.removeChild(r2);
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
p.appendChild(r2);
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
// Adding a radio element to an invalid group should make it invalid.
|
||||
p.removeChild(r1);
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
p.appendChild(r1);
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
// Adding a checked radio element to an invalid group should make it valid.
|
||||
p.removeChild(r1);
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
r1.checked = true;
|
||||
p.appendChild(r1);
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r2, true, false, false);
|
||||
r1.checked = false;
|
||||
|
||||
// Adding an invalid radio element by changing the name attribute.
|
||||
r2.name = 'c';
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
r2.name = 'a';
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
// Adding an element to an invalid radio group by changing the name attribute.
|
||||
r1.name = 'c';
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
r1.name = 'a';
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
// Adding a checked element to an invalid radio group with the name attribute.
|
||||
r1.name = 'c';
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
|
||||
r1.checked = true;
|
||||
r1.name = 'a';
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r2, true, false, false);
|
||||
r1.checked = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,6 @@ interface HTMLSelectElement : HTMLElement {
|
|||
[CEReactions, SetterThrows, Pure]
|
||||
attribute unsigned long size;
|
||||
|
||||
[ChromeOnly, Pure]
|
||||
readonly attribute boolean isCombobox;
|
||||
|
||||
[Pure]
|
||||
readonly attribute DOMString type;
|
||||
|
||||
|
@ -72,6 +69,10 @@ interface HTMLSelectElement : HTMLElement {
|
|||
// Chrome only interface
|
||||
|
||||
partial interface HTMLSelectElement {
|
||||
[ChromeOnly]
|
||||
undefined userFinishedInteracting(boolean changed);
|
||||
[ChromeOnly, Pure]
|
||||
readonly attribute boolean isCombobox;
|
||||
[ChromeOnly]
|
||||
attribute boolean openInParentProcess;
|
||||
[ChromeOnly]
|
||||
|
|
|
@ -377,15 +377,7 @@ void HTMLSelectEventListener::ComboboxMightHaveChanged() {
|
|||
|
||||
void HTMLSelectEventListener::FireOnInputAndOnChange() {
|
||||
RefPtr<HTMLSelectElement> element = mElement;
|
||||
// Dispatch the input event.
|
||||
DebugOnly<nsresult> rvIgnored = nsContentUtils::DispatchInputEvent(element);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
|
||||
"Failed to dispatch input event");
|
||||
|
||||
// Dispatch the change event.
|
||||
nsContentUtils::DispatchTrustedEvent(element->OwnerDoc(), element,
|
||||
u"change"_ns, CanBubble::eYes,
|
||||
Cancelable::eNo);
|
||||
element->UserFinishedInteracting(/* aChanged = */ true);
|
||||
}
|
||||
|
||||
static void FireDropDownEvent(HTMLSelectElement* aElement, bool aShow,
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if input isn't valid nor barred from constraint validation,
|
||||
and its checkedness has changed,
|
||||
it should be affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').checked = false;
|
||||
if (!document.getElementById('i').matches(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='checkbox' required>
|
||||
</body>
|
||||
</html>
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
function doTest() {
|
||||
document.getElementById('t').setCustomValidity('foo');
|
||||
document.documentElement.className='';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</head>
|
||||
<!-- Test: if input has a custom error, it should be affected by :-moz-ui-invalid
|
||||
pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body>
|
||||
<input class='invalid' id='t'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if input is not disabled and invalid, it is candidate for
|
||||
constraint validation and should be affected
|
||||
by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<script>
|
||||
function onLoadHandler()
|
||||
{
|
||||
var e = document.getElementById('i');
|
||||
e.setCustomValidity('foo');
|
||||
e.removeAttribute('disabled');
|
||||
document.documentElement.className='';
|
||||
}
|
||||
</script>
|
||||
<body onload="onLoadHandler();">
|
||||
<input class='invalid' id='i' disabled>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if input is no longer readonly, invalid and has it's value changed,
|
||||
it's affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').removeAttribute('readonly');
|
||||
document.getElementById('i').value = '';
|
||||
document.documentElement.className='';">
|
||||
<input class='invalid' id='i' readonly required>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if input isn't valid nor barred from constraint validation,
|
||||
and its value has changed,
|
||||
it should be affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value = 'foo';
|
||||
document.documentElement.className='';">
|
||||
<input id='i' class='invalid' type='email' value='bar'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if input isn't valid nor barred from constraint validation,
|
||||
but its default value hasn't been changed,
|
||||
it should not be affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value='';
|
||||
document.documentElement.className='';">
|
||||
<input id='i' class='invalid' type='file' required>
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if input isn't valid nor barred from constraint validation,
|
||||
and its value isn't the default value,
|
||||
it should be affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value='foo';
|
||||
document.documentElement.className='';">
|
||||
<input id='i' class='invalid' pattern='bar' value='f'>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if one radio in a group is suffering from a custom error, the other
|
||||
radio should not be invalid. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = false;
|
||||
document.getElementById('i1').setCustomValidity('foo');
|
||||
if (!document.getElementById('i1').matches(':-moz-ui-invalid') ||
|
||||
document.getElementById('i2').matches(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio'>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').checked = false;
|
||||
if (!document.getElementById('i').matches(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' required name='i'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if input isn't valid nor barred from constraint validation,
|
||||
and its checkedness has changed,
|
||||
it should be affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').checked = false;
|
||||
if (!document.getElementById('i').matches(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' required name='i'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if one radio in a group has the required attribute and no radio is
|
||||
checked, all radio in the group should have :-moz-ui-invalid
|
||||
pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = false;
|
||||
if (!document.getElementById('i1').matches(':-moz-ui-invalid') ||
|
||||
!document.getElementById('i2').matches(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if input isn't valid nor barred from constraint validation,
|
||||
it should be affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value='';
|
||||
document.documentElement.className='';">
|
||||
<input id='i' class='invalid' required>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if an input has a custom error when barred from constraint
|
||||
validation then move a type candidate for constraint validation,
|
||||
it should not be affected by :valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<script>
|
||||
function doTest()
|
||||
{
|
||||
var i = document.getElementById('i');
|
||||
i.setCustomValidity('foo');
|
||||
i.type = 'text';
|
||||
document.documentElement.className='';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
<body>
|
||||
<input class='invalid' type='button' id='i'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if input isn't valid nor barred from constraint validation,
|
||||
and its value is not the default value,
|
||||
it should be affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value='foo';
|
||||
document.documentElement.className='';">
|
||||
<input id='i' class='invalid' type='url'>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,41 +1,27 @@
|
|||
== input-valid.html input-ref.html
|
||||
fuzzy(0-64,0-4) == input-customerror.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-disabled.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-disabled.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-not-disabled.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-readonly.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-readonly.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-not-readonly-not-changed.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-not-readonly-changed.html input-ref.html
|
||||
== input-required-valid.html input-withtext-ref.html
|
||||
fuzzy(0-1,0-3) == input-required-invalid-default.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-required-invalid-changed.html input-ref.html
|
||||
fuzzy(0-2,0-5) == input-button.html input-button-ref.html
|
||||
fuzzy(0-2,0-5) == input-reset.html input-button-ref.html
|
||||
== input-email-invalid-default.html input-withtext-ref.html
|
||||
== input-email-invalid-changed.html input-withtext-ref.html
|
||||
fuzzy(0-2,0-5) == input-email-valid.html input-email-ref.html
|
||||
== input-url-invalid-changed.html input-withtext-ref.html
|
||||
== input-url-invalid-default.html input-withtext-ref.html
|
||||
== input-url-valid.html input-url-ref.html
|
||||
== input-pattern-valid.html input-withtext-ref.html
|
||||
== input-pattern-invalid-default.html input-withtext-ref.html
|
||||
== input-pattern-invalid-changed.html input-withtext-ref.html
|
||||
fuzzy(0-2,0-5) == input-type-barred.html input-button-ref.html
|
||||
fuzzy(0-64,0-4) == input-type-invalid.html input-ref.html
|
||||
== input-disabled-fieldset-1.html input-fieldset-ref.html
|
||||
fuzzy(0-1,0-3) == input-disabled-fieldset-2.html input-fieldset-ref.html
|
||||
fuzzy(0-1,0-3) == input-fieldset-legend.html input-fieldset-legend-ref.html
|
||||
== input-checkbox-required-invalid-changed.html success-ref.html
|
||||
== input-checkbox-required-invalid-default.html success-ref.html
|
||||
== input-radio-required-invalid-changed.html success-ref.html
|
||||
== input-radio-required-invalid-default.html success-ref.html
|
||||
== input-file-required-invalid-changed.html input-file-ref.html
|
||||
== input-file-required-invalid-default.html input-file-ref.html
|
||||
== input-radio-required.html success-ref.html
|
||||
== input-radio-customerror.html success-ref.html
|
||||
== input-radio-dyn-valid-1.html success-ref.html
|
||||
== input-radio-dyn-valid-2.html success-ref.html
|
||||
== input-radio-nogroup-required-valid.html success-ref.html
|
||||
== input-radio-nogroup-required-invalid.html success-ref.html
|
||||
# input type='hidden' shouldn't show
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
needs-focus fuzzy-if(geckoview,0-8,0-1) == select-valid.html select-ref.html
|
||||
fuzzy(0-1,0-3) needs-focus == select-invalid.html select-ref.html
|
||||
fuzzy(0-2,0-5) needs-focus == select-invalid-reset.html select-required-ref.html
|
||||
needs-focus == select-disabled.html select-disabled-ref.html
|
||||
needs-focus == select-dyn-disabled.html select-disabled-ref.html
|
||||
fuzzy(0-1,0-3) needs-focus == select-dyn-not-disabled.html select-ref.html
|
||||
fuzzy(0-2,0-5) needs-focus == select-required-invalid-1.html select-required-ref.html
|
||||
fuzzy(0-2,0-5) needs-focus == select-required-invalid-2.html select-required-ref.html
|
||||
fuzzy(0-2,0-5) needs-focus == select-required-invalid-changed-1.html select-required-ref.html
|
||||
fuzzy(0-2,0-5) needs-focus == select-required-invalid-changed-2.html select-required-ref.html
|
||||
fuzzy(0-2,0-5) needs-focus == select-required-valid.html select-required-ref.html
|
||||
needs-focus == select-required-multiple-invalid.html select-required-multiple-ref.html
|
||||
fuzzy(0-1,0-1000) needs-focus == select-required-multiple-invalid-changed.html select-required-multiple-ref.html
|
||||
needs-focus == select-required-multiple-valid.html select-required-multiple-ref.html
|
||||
fuzzy-if(!Android,0-2,0-10) fuzzy-if(Android,0-9,0-1) needs-focus == select-disabled-fieldset-1.html select-fieldset-ref.html
|
||||
fuzzy-if(!Android,0-2,0-10) fuzzy-if(Android,0-9,0-1) needs-focus == select-disabled-fieldset-2.html select-fieldset-ref.html
|
||||
fuzzy(0-2,0-10) needs-focus == select-fieldset-legend.html select-fieldset-legend-ref.html
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if select is not disabled and invalid, it is candidate for
|
||||
constraint validation and should be affected
|
||||
by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<script>
|
||||
function onLoadHandler()
|
||||
{
|
||||
var e = document.getElementById('s');
|
||||
e.setCustomValidity('foo');
|
||||
e.removeAttribute('disabled');
|
||||
document.documentElement.className='';
|
||||
}
|
||||
</script>
|
||||
<body onload="onLoadHandler();">
|
||||
<select class='invalid' id='s' disabled></select>
|
||||
</body>
|
||||
</html>
|
|
@ -1,10 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<fieldset>
|
||||
<legend>
|
||||
<select style="background-color: green;"></select>
|
||||
</legend>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if select has a disabled fieldset ancestor, but is in the first
|
||||
legend, it is not barred from constraint validation and should be
|
||||
affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<script>
|
||||
function onLoadHandler()
|
||||
{
|
||||
var e = document.getElementById('b');
|
||||
e.setCustomValidity('foo');
|
||||
document.documentElement.className='';
|
||||
}
|
||||
</script>
|
||||
<body onload="onLoadHandler();">
|
||||
<fieldset disabled>
|
||||
<legend>
|
||||
<select class='invalid' id='b'></select>
|
||||
</legend>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
|
@ -1,10 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if select has a custom error, it should be affected by :-moz-ui-invalid
|
||||
pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('s').setCustomValidity('foo');
|
||||
document.documentElement.className='';">
|
||||
<select class='invalid' id='s'></select>
|
||||
</body>
|
||||
</html>
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if select is required and the selected option has an empty
|
||||
string value and the selection did changed,
|
||||
:-moz-ui-invalid should apply. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('s').selectedIndex = 0;
|
||||
document.documentElement.className = '';">
|
||||
<select id='s' class='invalid' required>
|
||||
<option selected value="">foo</option>
|
||||
</select>
|
||||
</body>
|
||||
</html>
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if select is required and the selected option has an empty
|
||||
string value and the selection did changed,
|
||||
:-moz-ui-invalid should apply. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('s').selectedIndex = 0;
|
||||
document.documentElement.className = '';">
|
||||
<select id='s' class='invalid' required>
|
||||
<option value="">foo</option>
|
||||
</select>
|
||||
</body>
|
||||
</html>
|
|
@ -1,14 +1,10 @@
|
|||
== textarea-valid.html textarea-ref.html
|
||||
== textarea-customerror.html textarea-ref.html
|
||||
== textarea-disabled.html textarea-ref.html
|
||||
== textarea-dyn-disabled.html textarea-ref.html
|
||||
== textarea-dyn-not-disabled.html textarea-ref.html
|
||||
== textarea-readonly.html textarea-ref.html
|
||||
== textarea-dyn-readonly.html textarea-ref.html
|
||||
== textarea-dyn-not-readonly-not-changed.html textarea-ref.html
|
||||
== textarea-dyn-not-readonly-changed.html textarea-ref.html
|
||||
== textarea-required-valid.html textarea-withtext-ref.html
|
||||
== textarea-required-invalid.html textarea-ref.html
|
||||
== textarea-required-invalid-changed.html textarea-ref.html
|
||||
== textarea-disabled-fieldset-1.html textarea-fieldset-ref.html
|
||||
== textarea-disabled-fieldset-2.html textarea-fieldset-ref.html
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
function doTest() {
|
||||
document.getElementById('t').setCustomValidity('foo');
|
||||
document.documentElement.className='';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</head>
|
||||
<!-- Test: if textarea has a custom error, it should be affected by :-moz-ui-invalid
|
||||
pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body>
|
||||
<textarea class='invalid' id='t'></textarea>
|
||||
</body>
|
||||
</html>
|
|
@ -1,20 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if textarea is not disabled and invalid, it is candidate for
|
||||
constraint validation and should be affected
|
||||
by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<script>
|
||||
function doTest()
|
||||
{
|
||||
var e = document.getElementById('t');
|
||||
e.setCustomValidity('foo');
|
||||
e.removeAttribute('disabled');
|
||||
document.documentElement.className='';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
<body>
|
||||
<textarea class='invalid' id='t' disabled></textarea>
|
||||
</body>
|
||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
function doTest() {
|
||||
document.getElementById('t').removeAttribute('readonly');
|
||||
document.getElementById('t').value = '';
|
||||
document.documentElement.className='';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</head>
|
||||
<!-- Test: if textarea is no longer readonly and has it's value changed,
|
||||
it's affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body>
|
||||
<textarea class='invalid' id='t' readonly required></textarea>
|
||||
</body>
|
||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
function doTest() {
|
||||
document.getElementById('t').value = '';
|
||||
document.documentElement.className='';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</head>
|
||||
<!-- Test: if textarea isn't valid and it's value has been changed,
|
||||
it should be affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body>
|
||||
<textarea id='t' class='invalid' required></textarea>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if input is valid and its checkedness has changed,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').checked = false;
|
||||
if (!document.getElementById('i').matches(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='checkbox'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if input is not disabled and its value has been changed,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').removeAttribute('disabled');
|
||||
document.getElementById('i').value = '';
|
||||
document.documentElement.className='';">
|
||||
<input class='valid' id='i' disabled>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if input is no longer readonly and its value has been changed,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').removeAttribute('readonly');
|
||||
document.getElementById('i').value = '';
|
||||
document.documentElement.className='';">
|
||||
<input class='valid' id='i' readonly>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if input is valid and its value has been changed,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value = 'foo@bar.com';
|
||||
document.documentElement.className = '';">
|
||||
<input id='i' class='valid' type='email'>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if input is valid and its default value has been changed,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value='';
|
||||
document.documentElement.className='';">
|
||||
<input id='i' class='valid' type='file'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if input is valid and its value has been changed,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value = 'foo';
|
||||
document.documentElement.className = '';">
|
||||
<input id='i' class='valid' pattern='foo'>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = false;
|
||||
document.getElementById('i1').setCustomValidity('foo');
|
||||
if (document.getElementById('i1').matches(':-moz-ui-valid') ||
|
||||
!document.getElementById('i2').matches(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio'>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = true;
|
||||
if (!document.getElementById('i1').matches(':-moz-ui-valid') ||
|
||||
!document.getElementById('i2').matches(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = true;
|
||||
document.getElementById('i1').required = false;
|
||||
if (!document.getElementById('i1').matches(':-moz-ui-valid') ||
|
||||
!document.getElementById('i2').matches(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').checked = true;
|
||||
if (!document.getElementById('i').matches(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' required>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if input is valid and its value has been changed,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value = 'foo';
|
||||
document.documentElement.className = '';">
|
||||
<input id='i' class='valid' required>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if input is valid and its value has been changed,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value = 'http://mozilla.org/';
|
||||
document.documentElement.className = '';">
|
||||
<input id='i' class='valid' type='url'>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -3,38 +3,26 @@ fuzzy(0-11,0-4) == input-customerror.html input-ref.html
|
|||
== input-disabled.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-disabled.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-not-disabled.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-not-disabled-changed.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-readonly.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-readonly.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-not-readonly.html input-ref.html
|
||||
fuzzy(0-1,0-3) == input-dyn-not-readonly-changed.html input-ref.html
|
||||
== input-required-valid.html input-withtext-ref.html
|
||||
== input-required-valid-changed.html input-withtext-ref.html
|
||||
fuzzy(0-1,0-3) == input-required-invalid.html input-ref.html
|
||||
== input-button.html input-button-ref.html
|
||||
== input-reset.html input-button-ref.html
|
||||
== input-email-invalid.html input-withtext-ref.html
|
||||
== input-email-valid.html input-email-ref.html
|
||||
== input-email-valid-changed.html input-email-ref.html
|
||||
== input-url-invalid.html input-withtext-ref.html
|
||||
== input-url-valid.html input-url-ref.html
|
||||
== input-url-valid-changed.html input-url-ref.html
|
||||
== input-pattern-valid.html input-withtext-ref.html
|
||||
== input-pattern-valid-changed.html input-withtext-ref.html
|
||||
== input-pattern-invalid.html input-withtext-ref.html
|
||||
== input-type-barred.html input-button-ref.html
|
||||
fuzzy(0-64,0-4) == input-type-invalid.html input-ref.html
|
||||
== input-disabled-fieldset-1.html input-fieldset-ref.html
|
||||
fuzzy(0-1,0-3) == input-disabled-fieldset-2.html input-fieldset-ref.html
|
||||
fuzzy(0-1,0-3) == input-fieldset-legend.html input-fieldset-legend-ref.html
|
||||
== input-checkbox-valid-changed.html success-ref.html
|
||||
== input-checkbox-valid-default.html success-ref.html
|
||||
== input-file-valid-changed.html input-file-ref.html
|
||||
== input-file-valid-default.html input-file-ref.html
|
||||
== input-radio-required.html success-ref.html
|
||||
== input-radio-customerror.html success-ref.html
|
||||
== input-radio-dyn-valid-1.html success-ref.html
|
||||
== input-radio-dyn-valid-2.html success-ref.html
|
||||
== input-radio-nogroup-required-valid.html success-ref.html
|
||||
== input-radio-nogroup-required-invalid.html success-ref.html
|
||||
# input type='hidden' shouldn't show
|
||||
|
|
|
@ -7,11 +7,8 @@ fuzzy(0-1,0-3) needs-focus == select-dyn-not-disabled.html select-ref.html
|
|||
fuzzy(0-2,0-5) needs-focus == select-required-invalid.html select-required-ref.html
|
||||
fuzzy(0-2,0-5) needs-focus == select-required-valid-1.html select-required-ref.html
|
||||
fuzzy(0-2,0-5) needs-focus == select-required-valid-2.html select-required-ref.html
|
||||
fuzzy(0-2,0-5) needs-focus == select-required-valid-changed-1.html select-required-ref.html
|
||||
fuzzy(0-2,0-5) needs-focus == select-required-valid-changed-2.html select-required-ref.html
|
||||
needs-focus == select-required-multiple-invalid.html select-required-multiple-ref.html
|
||||
needs-focus == select-required-multiple-valid.html select-required-multiple-ref.html
|
||||
fuzzy(0-1,0-1000) needs-focus == select-required-multiple-valid-changed.html select-required-multiple-ref.html
|
||||
fuzzy-if(Android,0-9,0-1) needs-focus == select-disabled-fieldset-1.html select-fieldset-ref.html
|
||||
fuzzy-if(!Android,0-2,0-10) needs-focus == select-disabled-fieldset-2.html select-fieldset-ref.html
|
||||
fuzzy(0-2,0-10) needs-focus == select-fieldset-legend.html select-fieldset-legend-ref.html
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<script>
|
||||
function doTest() {
|
||||
document.getElementById('s').options[0].selected = false;
|
||||
document.getElementById('s').options[1].selected = false;
|
||||
document.getElementById('s').options[0].selected = true;
|
||||
document.getElementById('s').options[1].selected = true;
|
||||
document.documentElement.className='';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</head>
|
||||
<!-- Test: if select is required and has at least one option selected and the
|
||||
selection did changed, :-moz-ui-valid should not apply. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body>
|
||||
<select id='s' class='valid' required multiple>
|
||||
<option selected></option>
|
||||
<option selected>foo</option>
|
||||
</select>
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if select is required and has a selected option and the selection
|
||||
did changed, :-moz-ui-valid should apply. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('s').selectedIndex = 0;
|
||||
document.documentElement.className = '';">
|
||||
<select id='s' class='valid' required>
|
||||
<option>foo</option>
|
||||
</select>
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<!-- Test: if select is required and has a selected option and the selection
|
||||
did changed, :-moz-ui-valid should apply. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('s').selectedIndex = 0;
|
||||
document.documentElement.className = '';">
|
||||
<select id='s' class='valid' required>
|
||||
<option selected>foo</option>
|
||||
</select>
|
||||
</body>
|
||||
</html>
|
|
@ -3,13 +3,10 @@
|
|||
== textarea-disabled.html textarea-ref.html
|
||||
== textarea-dyn-disabled.html textarea-ref.html
|
||||
== textarea-dyn-not-disabled.html textarea-ref.html
|
||||
== textarea-dyn-not-disabled-changed.html textarea-ref.html
|
||||
== textarea-readonly.html textarea-ref.html
|
||||
== textarea-dyn-readonly.html textarea-ref.html
|
||||
== textarea-dyn-not-readonly.html textarea-ref.html
|
||||
== textarea-dyn-not-readonly-changed.html textarea-ref.html
|
||||
== textarea-required-valid.html textarea-withtext-ref.html
|
||||
== textarea-required-valid-changed.html textarea-withtext-ref.html
|
||||
== textarea-required-invalid.html textarea-ref.html
|
||||
== textarea-disabled-fieldset-1.html textarea-fieldset-ref.html
|
||||
== textarea-disabled-fieldset-2.html textarea-fieldset-ref.html
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
function doTest() {
|
||||
document.getElementById('t').removeAttribute('disabled');
|
||||
document.getElementById('t').value = '';
|
||||
document.documentElement.className='';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</head>
|
||||
<!-- Test: if textarea is not disabled and its value has been modifie,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body>
|
||||
<textarea class='valid' id='t' disabled></textarea>
|
||||
</body>
|
||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
function doTest() {
|
||||
document.getElementById('t').removeAttribute('readonly');
|
||||
document.getElementById('t').value = '';
|
||||
document.documentElement.className='';
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</head>
|
||||
<!-- Test: if textarea is no longer readonly and its value has been modified,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body>
|
||||
<textarea class='valid' id='t' readonly></textarea>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class='reftet-wait'>
|
||||
<!-- Test: if textarea is valid and its value has been modified,
|
||||
it should be affected by :-moz-ui-valid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('t').value = 'foo';
|
||||
document.documentElement.className = '';">
|
||||
<textarea id='t' class='valid' required></textarea>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
[user-invalid.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[:user-invalid selector properly interacts with submit & reset buttons]
|
||||
expected: FAIL
|
||||
|
||||
[required-input: A required input or textarea should match :user-invalid if a user types into it and then clears it before blurring.]
|
||||
expected:
|
||||
if os == "android": PASS
|
||||
FAIL
|
||||
|
||||
[:user-invalid selector should respond to user action]
|
||||
expected: FAIL
|
|
@ -1,8 +0,0 @@
|
|||
[user-valid.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[:user-valid selector properly interacts with submit & reset buttons]
|
||||
expected: FAIL
|
||||
|
||||
[:user-valid selector should respond to user action]
|
||||
expected: FAIL
|
|
@ -249,20 +249,12 @@ SelectContentHelper.prototype = {
|
|||
);
|
||||
|
||||
// Fire input and change events when selected option changes
|
||||
if (this.initialSelection !== selectedOption) {
|
||||
let inputEvent = new win.Event("input", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
});
|
||||
|
||||
let changeEvent = new win.Event("change", {
|
||||
bubbles: true,
|
||||
});
|
||||
|
||||
{
|
||||
let handlingUserInput = win.windowUtils.setHandlingUserInput(true);
|
||||
try {
|
||||
element.dispatchEvent(inputEvent);
|
||||
element.dispatchEvent(changeEvent);
|
||||
element.userFinishedInteracting(
|
||||
this.initialSelection !== selectedOption
|
||||
);
|
||||
} finally {
|
||||
handlingUserInput.destruct();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче