Bug 1425291 - Part 3. Add autocapitalize to InputContext. r=masayuki

Autocapitalize isn't applied if type is url, email or password. If these types,
truncate autocapitalize value in InputContext not to pass it to widget.

Differential Revision: https://phabricator.services.mozilla.com/D86676
This commit is contained in:
Makoto Kato 2020-09-15 14:27:00 +00:00
parent c48e63ea6f
commit e82e9e223d
8 changed files with 103 additions and 1 deletions

View File

@ -1747,6 +1747,16 @@ nsDOMWindowUtils::GetFocusedInputMode(nsAString& aInputMode) {
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetFocusedAutocapitalize(nsAString& aAutocapitalize) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return NS_ERROR_FAILURE;
}
aAutocapitalize = widget->GetInputContext().mAutocapitalize;
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetViewId(Element* aElement, nsViewID* aResult) {
if (aElement && nsLayoutUtils::FindIDFor(aElement, aResult)) {

View File

@ -1283,6 +1283,13 @@ void IMEStateManager::SetIMEState(const IMEState& aState,
ToLowerCase(context.mHTMLInputInputmode);
}
}
if (aContent->IsHTMLElement() && aState.IsEditable() &&
StaticPrefs::dom_forms_autocapitalize() &&
context.IsAutocapitalizeSupported()) {
nsGenericHTMLElement::FromNode(aContent)->GetAutocapitalize(
context.mAutocapitalize);
}
}
if (aAction.mCause == InputContextAction::CAUSE_UNKNOWN &&

View File

@ -1535,6 +1535,11 @@ interface nsIDOMWindowUtils : nsISupports {
*/
readonly attribute AString focusedInputMode;
/**
* Get the autocapitalize of the currently focused editing host, if any.
*/
readonly attribute AString focusedAutocapitalize;
/**
* Find the view ID for a given element. This is the reverse of
* findElementWithViewId().

View File

@ -79,7 +79,8 @@ std::ostream& operator<<(std::ostream& aStream, const InputContext& aContext) {
<< ", mOrigin=" << aContext.mOrigin << ", mHTMLInputType=\""
<< aContext.mHTMLInputType << "\", mHTMLInputInputmode=\""
<< aContext.mHTMLInputInputmode << "\", mActionHint=\""
<< aContext.mActionHint << "\", mMayBeIMEUnaware="
<< aContext.mActionHint << "\", mAutocapitalize=\""
<< aContext.mAutocapitalize << "\", mMayBeIMEUnaware="
<< (aContext.mMayBeIMEUnaware ? "true" : "false")
<< ", mIsPrivateBrowsing="
<< (aContext.mInPrivateBrowsing ? "true" : "false") << " }";

View File

@ -247,12 +247,20 @@ struct InputContext final {
mHTMLInputType.Truncate();
mHTMLInputInputmode.Truncate();
mActionHint.Truncate();
mAutocapitalize.Truncate();
}
bool IsPasswordEditor() const {
return mHTMLInputType.LowerCaseEqualsLiteral("password");
}
// https://html.spec.whatwg.org/dev/interaction.html#autocapitalization
bool IsAutocapitalizeSupported() const {
return !mHTMLInputType.EqualsLiteral("password") &&
!mHTMLInputType.EqualsLiteral("url") &&
!mHTMLInputType.EqualsLiteral("email");
}
IMEState mIMEState;
/* The type of the input if the input is a html input field */
@ -264,6 +272,9 @@ struct InputContext final {
/* A hint for the action that is performed when the input is submitted */
nsString mActionHint;
/* A hint for autocapitalize */
nsString mAutocapitalize;
/**
* mOrigin indicates whether this focus event refers to main or remote
* content.

View File

@ -947,6 +947,7 @@ struct ParamTraits<mozilla::widget::InputContext> {
WriteParam(aMsg, aParam.mHTMLInputType);
WriteParam(aMsg, aParam.mHTMLInputInputmode);
WriteParam(aMsg, aParam.mActionHint);
WriteParam(aMsg, aParam.mAutocapitalize);
WriteParam(aMsg, aParam.mOrigin);
WriteParam(aMsg, aParam.mMayBeIMEUnaware);
WriteParam(aMsg, aParam.mHasHandledUserInput);
@ -959,6 +960,7 @@ struct ParamTraits<mozilla::widget::InputContext> {
ReadParam(aMsg, aIter, &aResult->mHTMLInputType) &&
ReadParam(aMsg, aIter, &aResult->mHTMLInputInputmode) &&
ReadParam(aMsg, aIter, &aResult->mActionHint) &&
ReadParam(aMsg, aIter, &aResult->mAutocapitalize) &&
ReadParam(aMsg, aIter, &aResult->mOrigin) &&
ReadParam(aMsg, aIter, &aResult->mMayBeIMEUnaware) &&
ReadParam(aMsg, aIter, &aResult->mHasHandledUserInput) &&

View File

@ -6,6 +6,7 @@ skip-if = toolkit != 'windows' || headless # headless: Bug 1410525
[test_actionhint.html]
[test_assign_event_data.html]
skip-if = toolkit == "cocoa" || (toolkit == 'android' && debug) || android_version == '24' || (headless && os == "win") # Mac: Bug 933303, Android bug 1285414
[test_autocapitalize.html]
[test_keypress_event_with_alt_on_mac.html]
skip-if = toolkit != "cocoa"
[test_mouse_event_with_control_on_mac.html]

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<head>
<title>Tests for autocapitalize that is used by software keyboard</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/SpecialPowers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<div>
<input type="text" id="a1"><br>
<input type="text" id="a2" autocapitalize="characters"><br>
<input type="text" id="a3" autocapitalize="sentences"><br>
<input type="text" id="a4" autocapitalize="words"><br>
<input type="text" id="a5" autocapitalize="off"><br>
<input type="text" id="a6" autocapitalize="on"><br>
<input type="url" id="a7" autocapitalize="on"><br>
<input type="email" id="a8" autocapitalize="on"><br>
<input type="password" id="a9" autocapitalize="on"><br>
<textarea id="b1" autocapitalize="characters"></textarea><br>
<div contenteditable id="c1" autocapitalize="sentences"></div><br>
<form><input type="text" id="d1" autocapitalize="words"></form><br>
<form autocapitalize="on"><input type="text" id="d2"></form><br>
<form autocapitalize="off"><input type="text" id="d3" autocapitalize="on"></form><br>
</div>
<pre id="test">
<script class=testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(async () => {
const tests = [
{ id: "a1", autocapitalize: "", desc: "input without autocapitalize" },
{ id: "a2", autocapitalize: "characters", desc: "input with autocapitalize=characters" },
{ id: "a3", autocapitalize: "sentences", desc: "input with autocapitalize=sentences" },
{ id: "a4", autocapitalize: "words", desc: "input with autocapitalize=words" },
{ id: "a5", autocapitalize: "none", desc: "input with autocapitalize=off" },
{ id: "a6", autocapitalize: "sentences", desc: "input with autocapitalize=on" },
{ id: "a7", autocapitalize: "", desc: "input with type=url and autocapitalize=on" },
{ id: "a8", autocapitalize: "", desc: "input with type=email and autocapitalize=on" },
{ id: "a9", autocapitalize: "", desc: "input with type=password and autocapitalize=on" },
{ id: "b1", autocapitalize: "characters", desc: "textarea with autocapitalize=characters" },
{ id: "c1", autocapitalize: "sentences", desc: "contenteditable with autocapitalize=sentences" },
{ id: "d1", autocapitalize: "words", desc: "input with autocapitalize=words in form" },
{ id: "d2", autocapitalize: "sentences", desc: "input in form with autocapitalize=on" },
{ id: "d3", autocapitalize: "sentences", desc: "input with autocapitalize=on in form" },
];
await SpecialPowers.setBoolPref("dom.forms.autocapitalize", true);
for (let test of tests) {
document.getElementById(test.id).focus();
is(SpecialPowers.DOMWindowUtils.focusedAutocapitalize, test.autocapitalize, test.desc);
}
SpecialPowers.clearUserPref("dom.forms.autocapitalize");
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>