Bug 665884 - Redirect focus from <input type=number> to its anonymous text control, and get autofocus working. r=dbaron

This commit is contained in:
Jonathan Watt
2011-06-21 16:13:12 +02:00
parent f1a7185f76
commit eeeb824ada
12 changed files with 172 additions and 1 deletions

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html class="reftest-wait">
<!-- In this case we're using reftest-wait to make sure the test doesn't
get snapshotted before it's been focused. We're not testing
invalidation so we don't need to listen for MozReftestInvalidate.
-->
<head>
<meta charset="utf-8">
</head>
<body onload="document.getElementsByTagName('input')[0].focus();">
<input onfocus="document.documentElement.removeAttribute('class');"
style="-moz-appearance: none;">
<!-- div to cover spin box area for type=number to type=text comparison -->
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
</body>
</html>

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html class="reftest-wait">
<!-- In this case we're using reftest-wait to make sure the test doesn't
get snapshotted before it's been focused. We're not testing
invalidation so we don't need to listen for MozReftestInvalidate.
-->
<head>
<meta charset="utf-8">
<script>
function focusHandler() {
setTimeout(function() {
document.documentElement.removeAttribute('class');
}, 0);
}
</script>
</head>
<body>
<input type="number" autofocus onfocus="focusHandler();"
style="-moz-appearance: none;">
<!-- div to cover spin box area for type=number to type=text comparison -->
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
</body>
</html>

View File

@@ -1,5 +1,6 @@
needs-focus == input-load.html input-ref.html
needs-focus == input-create.html input-ref.html
fails-if(Android) needs-focus == input-number.html input-number-ref.html # bug 940764
needs-focus == button-load.html button-ref.html
needs-focus == button-create.html button-ref.html
needs-focus == textarea-load.html textarea-ref.html

View File

@@ -19,6 +19,7 @@
#include "nsIControllers.h"
#include "nsIStringBundle.h"
#include "nsFocusManager.h"
#include "nsNumberControlFrame.h"
#include "nsPIDOMWindow.h"
#include "nsContentCID.h"
#include "nsIComponentManager.h"
@@ -2960,9 +2961,41 @@ HTMLInputElement::SetCheckedInternal(bool aChecked, bool aNotify)
UpdateState(aNotify);
}
void
HTMLInputElement::Blur(ErrorResult& aError)
{
if (mType == NS_FORM_INPUT_NUMBER) {
// Blur our anonymous text control, if we have one. (DOM 'change' event
// firing and other things depend on this.)
nsNumberControlFrame* numberControlFrame =
do_QueryFrame(GetPrimaryFrame());
if (numberControlFrame) {
HTMLInputElement* textControl = numberControlFrame->GetAnonTextControl();
if (textControl) {
textControl->Blur(aError);
return;
}
}
}
nsGenericHTMLElement::Blur(aError);
}
void
HTMLInputElement::Focus(ErrorResult& aError)
{
if (mType == NS_FORM_INPUT_NUMBER) {
// Focus our anonymous text control, if we have one.
nsNumberControlFrame* numberControlFrame =
do_QueryFrame(GetPrimaryFrame());
if (numberControlFrame) {
HTMLInputElement* textControl = numberControlFrame->GetAnonTextControl();
if (textControl) {
textControl->Focus(aError);
return;
}
}
}
if (mType != NS_FORM_INPUT_FILE) {
nsGenericHTMLElement::Focus(aError);
return;

View File

@@ -108,6 +108,7 @@ public:
virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
using nsGenericHTMLElement::Focus;
virtual void Blur(ErrorResult& aError) MOZ_OVERRIDE;
virtual void Focus(ErrorResult& aError) MOZ_OVERRIDE;
// nsIDOMHTMLInputElement

View File

@@ -158,7 +158,7 @@ public:
SetHTMLIntAttr(nsGkAtoms::tabindex, aTabIndex, aError);
}
virtual void Focus(mozilla::ErrorResult& aError);
void Blur(mozilla::ErrorResult& aError);
virtual void Blur(mozilla::ErrorResult& aError);
void GetAccessKey(nsString& aAccessKey)
{
GetHTMLAttr(nsGkAtoms::accesskey, aAccessKey);

View File

@@ -5,7 +5,10 @@
#include "nsNumberControlFrame.h"
#include "HTMLInputElement.h"
#include "nsIFocusManager.h"
#include "nsIPresShell.h"
#include "nsFocusManager.h"
#include "nsFontMetrics.h"
#include "nsFormControlFrame.h"
#include "nsGkAtoms.h"
@@ -17,6 +20,7 @@
#include "nsStyleSet.h"
using namespace mozilla;
using namespace mozilla::dom;
nsIFrame*
NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -27,6 +31,7 @@ NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
NS_IMPL_FRAMEARENA_HELPERS(nsNumberControlFrame)
NS_QUERYFRAME_HEAD(nsNumberControlFrame)
NS_QUERYFRAME_ENTRY(nsNumberControlFrame)
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
@@ -218,6 +223,14 @@ nsNumberControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("text"), PR_FALSE);
if (mContent->AsElement()->State().HasState(NS_EVENT_STATE_FOCUS)) {
// We don't want to focus the frame but the text field.
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mTextField);
NS_ASSERTION(element, "Really, this should be a nsIDOMElement!");
fm->SetFocus(element, 0);
}
// Create the ::-moz-number-spin-box pseudo-element:
rv = MakeAnonymousElement(getter_AddRefs(mSpinBox),
outerWrapperCI.mChildren,
@@ -251,6 +264,12 @@ nsNumberControlFrame::GetType() const
return nsGkAtoms::numberControlFrame;
}
HTMLInputElement*
nsNumberControlFrame::GetAnonTextControl()
{
return mTextField ? HTMLInputElement::FromContent(mTextField) : nullptr;
}
void
nsNumberControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
uint32_t aFilter)

View File

@@ -13,6 +13,12 @@
class nsPresContext;
namespace mozilla {
namespace dom {
class HTMLInputElement;
}
}
/**
* This frame type is used for <input type=number>.
*/
@@ -22,9 +28,12 @@ class nsNumberControlFrame MOZ_FINAL : public nsContainerFrame
friend nsIFrame*
NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
typedef mozilla::dom::HTMLInputElement HTMLInputElement;
nsNumberControlFrame(nsStyleContext* aContext);
public:
NS_DECL_QUERYFRAME_TARGET(nsNumberControlFrame)
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS
@@ -56,6 +65,8 @@ public:
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
}
HTMLInputElement* GetAnonTextControl();
private:
nsresult MakeAnonymousElement(nsIContent** aResult,

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html class="reftest-wait">
<!-- In this case we're using reftest-wait to make sure the test doesn't
get snapshotted before it's been focused. We're not testing
invalidation so we don't need to listen for MozReftestInvalidate.
-->
<head>
<meta charset="utf-8">
<script>
function end() {
setTimeout(function() {
document.documentElement.className = "";
}, 0);
}
</script>
</head>
<body>
<input style="-moz-appearance:none;"><br>
<input autofocus onfocus="end();"
style="-moz-appearance:none;">
<!-- div to cover spin box area for type=number to type=text comparison -->
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
</body>
</html>

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html class="reftest-wait">
<!-- In this case we're using reftest-wait to make sure the test doesn't
get snapshotted before it's been focused. We're not testing
invalidation so we don't need to listen for MozReftestInvalidate.
-->
<head>
<meta charset="utf-8">
<script>
function begin() {
document.getElementsByTagName('input')[1].focus();
}
function end() {
setTimeout(function() {
document.documentElement.className = "";
}, 0);
}
</script>
</head>
<body>
<input type='number' autofocus onfocus="begin();"
style="-moz-appearance:none;"><br>
<input type='number' onfocus="end();"
style="-moz-appearance:none;">
<!-- div to cover spin box area for type=number to type=text comparison -->
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
</body>
</html>

View File

@@ -14,3 +14,6 @@ skip-if(!Android&&!B2G) == number-same-as-text-unthemed.html number-same-as-text
fuzzy-if(/^Windows\x20NT\x205\.1/.test(http.oscpu),64,4) fuzzy-if(cocoaWidget,63,4) == to-number-from-other-type-unthemed-1.html to-number-from-other-type-unthemed-1-ref.html
== from-number-to-other-type-unthemed-1.html from-number-to-other-type-unthemed-1-ref.html
# focus
fails-if(B2G) needs-focus == focus-handling.html focus-handling-ref.html # bug 940760

View File

@@ -899,6 +899,8 @@ input[type=number]::-moz-number-wrapper {
input[type=number]::-moz-number-text {
-moz-appearance: none;
/* work around autofocus bug 939248 on initial load */
-moz-user-modify: read-write;
flex: 1;
padding: 0;
border: 0;