Bug 665884 - Redirect focus from <input type=number> to its anonymous text control, and get autofocus working. r=dbaron
This commit is contained in:
@@ -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>
|
||||
|
||||
26
content/html/content/reftests/autofocus/input-number.html
Normal file
26
content/html/content/reftests/autofocus/input-number.html
Normal 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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
26
layout/reftests/forms/input/number/focus-handling-ref.html
Normal file
26
layout/reftests/forms/input/number/focus-handling-ref.html
Normal 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>
|
||||
32
layout/reftests/forms/input/number/focus-handling.html
Normal file
32
layout/reftests/forms/input/number/focus-handling.html
Normal 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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user