Bug 1386530. Fix handling of type changes that affect validity state to properly notify state changes. r=jessica

MozReview-Commit-ID: Khhzi1HyCpt
This commit is contained in:
Boris Zbarsky 2017-09-22 15:47:16 -04:00
Родитель 5e2db259a2
Коммит 86db2ae4fd
24 изменённых файлов: 509 добавлений и 7 удалений

Просмотреть файл

@ -3350,7 +3350,9 @@ HTMLInputElement::SetCheckedInternal(bool aChecked, bool aNotify)
}
}
UpdateAllValidityStates(aNotify);
// No need to update element state, since we're about to call
// UpdateState anyway.
UpdateAllValidityStatesButNotElementState();
// Notify the document that the CSS :checked pseudoclass for this element
// has changed state.
@ -5039,8 +5041,9 @@ HTMLInputElement::HandleTypeChange(uint8_t aNewType, bool aNotify)
UpdateHasRange();
// Do not notify, it will be done after if needed.
UpdateAllValidityStates(false);
// Update validity states, but not element state. We'll update
// element state later, as part of this attribute change.
UpdateAllValidityStatesButNotElementState();
UpdateApzAwareFlag();
@ -7357,6 +7360,16 @@ void
HTMLInputElement::UpdateAllValidityStates(bool aNotify)
{
bool validBefore = IsValid();
UpdateAllValidityStatesButNotElementState();
if (validBefore != IsValid()) {
UpdateState(aNotify);
}
}
void
HTMLInputElement::UpdateAllValidityStatesButNotElementState()
{
UpdateTooLongValidityState();
UpdateTooShortValidityState();
UpdateValueMissingValidityState();
@ -7366,10 +7379,6 @@ HTMLInputElement::UpdateAllValidityStates(bool aNotify)
UpdateRangeUnderflowValidityState();
UpdateStepMismatchValidityState();
UpdateBadInputValidityState();
if (validBefore != IsValid()) {
UpdateState(aNotify);
}
}
void

Просмотреть файл

@ -368,7 +368,14 @@ public:
void UpdateRangeUnderflowValidityState();
void UpdateStepMismatchValidityState();
void UpdateBadInputValidityState();
// Update all our validity states and then update our element state
// as needed. aNotify controls whether the element state update
// needs to notify.
void UpdateAllValidityStates(bool aNotify);
// Update all our validity states without updating element state.
// This should be called instead of UpdateAllValidityStates any time
// we're guaranteed that element state will be updated anyway.
void UpdateAllValidityStatesButNotElementState();
void UpdateBarredFromConstraintValidation();
nsresult GetValidationMessage(nsAString& aValidationMessage,
ValidityStateType aType) override;

Просмотреть файл

@ -12,3 +12,6 @@ include percentage/reftest.list
include hidden/reftest.list
include color/reftest.list
include datetime/reftest.list
== selector-read-write-type-change-001.html selector-read-write-type-change-001-ref.html
== selector-read-write-type-change-002.html selector-read-write-type-change-002-ref.html

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<style>
span { color: green; }
</style>
</head>
<body>
<input type="button"><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>Check for correctly updating :read-write matching on type change</title>
<link rel="match" href="selector-read-write-type-change-001-ref.html">
<style>
span { color: green; }
:-moz-read-write + span { color: red }
</style>
<script>
onload = function() {
document.querySelector("input").type = "button";
}
</script>
</head>
<body>
<input required><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<style>
span { color: green; }
</style>
</head>
<body>
<input required><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>Check for correctly updating :read-write matching on type change</title>
<link rel="match" href="selector-read-write-type-change-002-ref.html">
<style>
span { color: red; }
:-moz-read-write + span { color: green }
</style>
<script>
onload = function() {
// setTimeout because in some browsers apparently a toplevel restyle
// happens right after the load event fires?
setTimeout(function() {
document.querySelector("input").type = "";
document.documentElement.className = "";
}, 10);
}
</script>
</head>
<body>
<input type="hidden" required><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -153607,6 +153607,66 @@
{}
]
],
"css/selectors4/selector-placeholder-shown-type-change-001.html": [
[
"/css/selectors4/selector-placeholder-shown-type-change-001.html",
[
[
"/css/selectors4/selector-placeholder-shown-type-change-001-ref.html",
"=="
]
],
{}
]
],
"css/selectors4/selector-placeholder-shown-type-change-002.html": [
[
"/css/selectors4/selector-placeholder-shown-type-change-002.html",
[
[
"/css/selectors4/selector-placeholder-shown-type-change-002-ref.html",
"=="
]
],
{}
]
],
"css/selectors4/selector-placeholder-shown-type-change-003.html": [
[
"/css/selectors4/selector-placeholder-shown-type-change-003.html",
[
[
"/css/selectors4/selector-placeholder-shown-type-change-003-ref.html",
"=="
]
],
{}
]
],
"css/selectors4/selector-read-write-type-change-001.html": [
[
"/css/selectors4/selector-read-write-type-change-001.html",
[
[
"/css/selectors4/selector-read-write-type-change-001-ref.html",
"=="
]
],
{}
]
],
"css/selectors4/selector-read-write-type-change-002.html": [
[
"/css/selectors4/selector-read-write-type-change-002.html",
[
[
"/css/selectors4/selector-read-write-type-change-002-ref.html",
"=="
]
],
{}
]
],
"css/selectors4/selector-required.html": [
[
"/css/selectors4/selector-required.html",
@ -153619,6 +153679,30 @@
{}
]
],
"css/selectors4/selector-required-type-change-001.html": [
[
"/css/selectors4/selector-required-type-change-001.html",
[
[
"/css/selectors4/selector-required-type-change-001-ref.html",
"=="
]
],
{}
]
],
"css/selectors4/selector-required-type-change-002.html": [
[
"/css/selectors4/selector-required-type-change-002.html",
[
[
"/css/selectors4/selector-required-type-change-002-ref.html",
"=="
]
],
{}
]
],
"css/selectors4/selectors-dir-selector-ltr-001.html": [
[
"/css/selectors4/selectors-dir-selector-ltr-001.html",
@ -253234,11 +253318,46 @@
{}
]
],
"css/selectors4/selector-placeholder-shown-type-change-001-ref.html": [
[
{}
]
],
"css/selectors4/selector-placeholder-shown-type-change-002-ref.html": [
[
{}
]
],
"css/selectors4/selector-placeholder-shown-type-change-003-ref.html": [
[
{}
]
],
"css/selectors4/selector-read-write-type-change-001-ref.html": [
[
{}
]
],
"css/selectors4/selector-read-write-type-change-002-ref.html": [
[
{}
]
],
"css/selectors4/selector-required-ref.html": [
[
{}
]
],
"css/selectors4/selector-required-type-change-001-ref.html": [
[
{}
]
],
"css/selectors4/selector-required-type-change-002-ref.html": [
[
{}
]
],
"css/support/1x1-green.png": [
[
{}
@ -545754,10 +545873,66 @@
"607553f41a33ce3630752cdf027c9f904833a19d",
"reftest"
],
"css/selectors4/selector-placeholder-shown-type-change-001-ref.html": [
"92303d06943581738f58ff5d342ef1336539f66a",
"support"
],
"css/selectors4/selector-placeholder-shown-type-change-002-ref.html": [
"ac3a88a758fd0ccc67077993d59bfb34eadf3931",
"support"
],
"css/selectors4/selector-placeholder-shown-type-change-003-ref.html": [
"ac3a88a758fd0ccc67077993d59bfb34eadf3931",
"support"
],
"css/selectors4/selector-placeholder-shown-type-change-001.html": [
"afb7a260d6f1c7da337a1f20a62778d1d6e302c4",
"reftest"
],
"css/selectors4/selector-placeholder-shown-type-change-002.html": [
"df0cbd1b178d72de9f70d0e603c30858508c2edd",
"reftest"
],
"css/selectors4/selector-placeholder-shown-type-change-003.html": [
"36046107e0f3763e219a2316ab6232785a325257",
"reftest"
],
"css/selectors4/selector-read-write-type-change-001-ref.html": [
"812f07e03f5bbf86feb2d8eefe17aeaa7bd69970",
"support"
],
"css/selectors4/selector-read-write-type-change-001.html": [
"95da0fbd6aafb8dcecb6f39e5cc8572f536e7eb5",
"reftest"
],
"css/selectors4/selector-read-write-type-change-002-ref.html": [
"3579aa13253d99a430ce17ba1acd629a22261097",
"support"
],
"css/selectors4/selector-read-write-type-change-002.html": [
"0bb1111fd76582a433204bce32852fc0a5dc5458",
"reftest"
],
"css/selectors4/selector-required-ref.html": [
"815bc765614b4c2e3d8f8f6303e6bb2ee0989c23",
"support"
],
"css/selectors4/selector-required-type-change-001-ref.html": [
"812f07e03f5bbf86feb2d8eefe17aeaa7bd69970",
"support"
],
"css/selectors4/selector-required-type-change-001.html": [
"211b7b71cf1073dd15491b78b0152f9b7a5e9aec",
"reftest"
],
"css/selectors4/selector-required-type-change-002-ref.html": [
"3579aa13253d99a430ce17ba1acd629a22261097",
"support"
],
"css/selectors4/selector-required-type-change-002.html": [
"f27dbc7bd1e2aa0753bcae73fdf2d83f7248118a",
"reftest"
],
"css/selectors4/selector-required.html": [
"601b8b8426c64717f82831e6258f8fe4188c797c",
"reftest"

Просмотреть файл

@ -0,0 +1,4 @@
[selector-placeholder-shown-type-change-001.html]
type: reftest
expected: FAIL
bug: 1401657

Просмотреть файл

@ -0,0 +1,4 @@
[selector-read-write-type-change-002.html]
type: reftest
expected: FAIL
bug: 312971

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<style>
span { color: green; }
</style>
</head>
<body>
<input placeholder="text"><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>Check for correctly updating :placeholder-shown matching on type change</title>
<link rel="match" href="selector-placeholder-shown-type-change-001-ref.html">
<style>
span { color: red; }
:placeholder-shown + span { color: green }
</style>
<script>
onload = function() {
// setTimeout because in some browsers apparently a toplevel restyle
// happens right after the load event fires?
setTimeout(function() {
document.querySelector("input").type = "";
document.documentElement.className = "";
}, 10);
}
</script>
</head>
<body>
<input type="hidden" placeholder="text"><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<style>
span { color: green; }
</style>
</head>
<body>
<span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>Check for correctly updating :placeholder-shown matching on type change</title>
<link rel="match" href="selector-placeholder-shown-type-change-002-ref.html">
<style>
span { color: green; }
:placeholder-shown + span { color: red }
</style>
<script>
onload = function() {
// setTimeout because in some browsers apparently a toplevel restyle
// happens right after the load event fires?
setTimeout(function() {
document.querySelector("input").type = "hidden";
document.documentElement.className = "";
}, 10);
}
</script>
</head>
<body>
<input placeholder="text"><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<style>
span { color: green; }
</style>
</head>
<body>
<span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>Check for correctly updating :placeholder-shown matching on type change</title>
<link rel="match" href="selector-placeholder-shown-type-change-003-ref.html">
<style>
span { color: green; }
:placeholder-shown + span { color: red }
</style>
<script>
onload = function() {
// setTimeout because in some browsers apparently a toplevel restyle
// happens right after the load event fires?
setTimeout(function() {
document.querySelector("input").type = "hidden";
document.documentElement.className = "";
}, 10);
}
</script>
</head>
<body>
<input required placeholder="text"><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<style>
span { color: green; }
</style>
</head>
<body>
<input type="button"><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>Check for correctly updating :read-write matching on type change</title>
<link rel="match" href="selector-read-write-type-change-001-ref.html">
<style>
span { color: green; }
:read-write + span { color: red }
</style>
<script>
onload = function() {
document.querySelector("input").type = "button";
}
</script>
</head>
<body>
<input required><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<style>
span { color: green; }
</style>
</head>
<body>
<input required><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>Check for correctly updating :read-write matching on type change</title>
<link rel="match" href="selector-read-write-type-change-002-ref.html">
<style>
span { color: red; }
:read-write + span { color: green }
</style>
<script>
onload = function() {
// setTimeout because in some browsers apparently a toplevel restyle
// happens right after the load event fires?
setTimeout(function() {
document.querySelector("input").type = "";
document.documentElement.className = "";
}, 10);
}
</script>
</head>
<body>
<input type="hidden" required><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<style>
span { color: green; }
</style>
</head>
<body>
<input type="button"><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>Check for correctly updating :required matching on type change</title>
<link rel="match" href="selector-required-type-change-001-ref.html">
<style>
span { color: green; }
:required + span { color: red }
</style>
<script>
onload = function() {
document.querySelector("input").type = "button";
}
</script>
</head>
<body>
<input required><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<style>
span { color: green; }
</style>
</head>
<body>
<input required><span>This should be green</span>
</body>
</html>

Просмотреть файл

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>Check for correctly updating :required matching on type change</title>
<link rel="match" href="selector-required-type-change-002-ref.html">
<style>
span { color: red; }
:required + span { color: green }
</style>
<script>
onload = function() {
// setTimeout because in some browsers apparently a toplevel restyle
// happens right after the load event fires?
setTimeout(function() {
document.querySelector("input").type = "";
document.documentElement.className = "";
}, 10);
}
</script>
</head>
<body>
<input type="hidden" required><span>This should be green</span>
</body>
</html>