Bug 1439155: Be consistent about what does readonly apply to. r=smaug

MozReview-Commit-ID: 4NiDe7pUzGa

--HG--
extra : rebase_source : 97c42c12cbeffaf360c9b91f4ee8bc7b95e4e48e
This commit is contained in:
Emilio Cobos Álvarez 2018-02-22 08:07:55 +01:00
Родитель c81c7b1390
Коммит 8010ae3a8d
6 изменённых файлов: 112 добавлений и 49 удалений

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

@ -6909,46 +6909,6 @@ HTMLInputElement::IsMutable() const
HasAttr(kNameSpaceID_None, nsGkAtoms::readonly));
}
bool
HTMLInputElement::DoesReadOnlyApply() const
{
switch (mType)
{
case NS_FORM_INPUT_HIDDEN:
case NS_FORM_INPUT_BUTTON:
case NS_FORM_INPUT_IMAGE:
case NS_FORM_INPUT_RESET:
case NS_FORM_INPUT_SUBMIT:
case NS_FORM_INPUT_RADIO:
case NS_FORM_INPUT_FILE:
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RANGE:
case NS_FORM_INPUT_COLOR:
return false;
#ifdef DEBUG
case NS_FORM_INPUT_TEXT:
case NS_FORM_INPUT_PASSWORD:
case NS_FORM_INPUT_SEARCH:
case NS_FORM_INPUT_TEL:
case NS_FORM_INPUT_EMAIL:
case NS_FORM_INPUT_URL:
case NS_FORM_INPUT_NUMBER:
case NS_FORM_INPUT_DATE:
case NS_FORM_INPUT_TIME:
case NS_FORM_INPUT_MONTH:
case NS_FORM_INPUT_WEEK:
case NS_FORM_INPUT_DATETIME_LOCAL:
return true;
default:
MOZ_ASSERT_UNREACHABLE("Unexpected input type in DoesReadOnlyApply()");
return true;
#else // DEBUG
default:
return true;
#endif // DEBUG
}
}
bool
HTMLInputElement::DoesRequiredApply() const
{

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

@ -1172,11 +1172,6 @@ protected:
*/
bool IsMutable() const;
/**
* Returns if the readonly attribute applies for the current type.
*/
bool DoesReadOnlyApply() const;
/**
* Returns if the min and max attributes apply for the current type.
*/

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

@ -2048,6 +2048,52 @@ nsGenericHTMLFormElement::CanBeDisabled() const
type != NS_FORM_OUTPUT;
}
bool
nsGenericHTMLFormElement::DoesReadOnlyApply() const
{
int32_t type = ControlType();
if (!(type & NS_FORM_INPUT_ELEMENT) && type != NS_FORM_TEXTAREA) {
return false;
}
switch (type)
{
case NS_FORM_INPUT_HIDDEN:
case NS_FORM_INPUT_BUTTON:
case NS_FORM_INPUT_IMAGE:
case NS_FORM_INPUT_RESET:
case NS_FORM_INPUT_SUBMIT:
case NS_FORM_INPUT_RADIO:
case NS_FORM_INPUT_FILE:
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RANGE:
case NS_FORM_INPUT_COLOR:
return false;
#ifdef DEBUG
case NS_FORM_TEXTAREA:
case NS_FORM_INPUT_TEXT:
case NS_FORM_INPUT_PASSWORD:
case NS_FORM_INPUT_SEARCH:
case NS_FORM_INPUT_TEL:
case NS_FORM_INPUT_EMAIL:
case NS_FORM_INPUT_URL:
case NS_FORM_INPUT_NUMBER:
case NS_FORM_INPUT_DATE:
case NS_FORM_INPUT_TIME:
case NS_FORM_INPUT_MONTH:
case NS_FORM_INPUT_WEEK:
case NS_FORM_INPUT_DATETIME_LOCAL:
return true;
default:
MOZ_ASSERT_UNREACHABLE("Unexpected input type in DoesReadOnlyApply()");
return true;
#else // DEBUG
default:
return true;
#endif // DEBUG
}
}
bool
nsGenericHTMLFormElement::IsHTMLFocusable(bool aWithMouse,
bool* aIsFocusable,
@ -2081,10 +2127,8 @@ nsGenericHTMLFormElement::IntrinsicState() const
// Make the text controls read-write
if (!state.HasState(NS_EVENT_STATE_MOZ_READWRITE) &&
IsTextOrNumberControl(/*aExcludePassword*/ false)) {
bool roState = GetBoolAttr(nsGkAtoms::readonly);
if (!roState) {
DoesReadOnlyApply()) {
if (!GetBoolAttr(nsGkAtoms::readonly)) {
state |= NS_EVENT_STATE_MOZ_READWRITE;
state &= ~NS_EVENT_STATE_MOZ_READONLY;
}

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

@ -1100,6 +1100,11 @@ public:
*/
bool CanBeDisabled() const;
/**
* Returns if the readonly attribute applies.
*/
bool DoesReadOnlyApply() const;
virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
int32_t* aTabIndex) override;

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

@ -65,3 +65,4 @@ skip-if = e10s || toolkit == 'android' # Bug 1170129 - vertical <select> popup n
[test_textarea_resize.html]
skip-if = toolkit == 'android'
[test_bug1327129.html]
[test_readonly.html]

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

@ -0,0 +1,58 @@
<!doctype html>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="should-apply">
<textarea></textarea>
<input type="text">
<input type="password">
<input type="search">
<input type="tel">
<input type="email">
<input type="url">
<input type="number">
<input type="date">
<input type="time">
<input type="month">
<input type="week">
<input type="datetime-local">
</div>
<div id="should-not-apply">
<input type="hidden">
<input type="button">
<input type="image">
<input type="reset">
<input type="submit">
<input type="radio">
<input type="file">
<input type="checkbox">
<input type="range">
<input type="color">
</div>
<script>
for (const element of Array.from(document.querySelectorAll('#should-apply *'))) {
let elementDesc = element.tagName.toLowerCase();
if (elementDesc === "input")
elementDesc += ` type="${element.type}"`;
test(function() {
assert_false(element.matches(':-moz-read-only'), "Shouldn't be initially read-only");
assert_true(element.matches(':-moz-read-write'), "Thus should be read-write");
element.setAttribute("readonly", "readonly");
assert_true(element.matches(':-moz-read-only'), "Should become read-only");
assert_false(element.matches(':-moz-read-write'), "Thus should stop being read-write");
}, elementDesc);
}
for (const element of Array.from(document.querySelectorAll('#should-not-apply *'))) {
let elementDesc = element.tagName.toLowerCase();
if (elementDesc === "input")
elementDesc += ` type="${element.type}"`;
test(function() {
assert_true(element.matches(':-moz-read-only'), "Should match read-only");
assert_false(element.matches(':-moz-read-write'), "Should not be read-write");
element.setAttribute("readonly", "readonly");
assert_true(element.matches(':-moz-read-only'), "Should keep matching read-only");
assert_false(element.matches(':-moz-read-write'), "Should still not be read-write");
}, elementDesc);
}
</script>