mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 555559 - Implement <input type="email">. r=smaug,sicking sr=jst a2.0=blocking
This commit is contained in:
parent
dd7e331508
commit
957d62aa07
@ -1790,6 +1790,7 @@ nsEventStateManager::FireContextClick()
|
||||
PRInt32 type = formCtrl->GetType();
|
||||
|
||||
allowedToDispatch = (type == NS_FORM_INPUT_TEXT ||
|
||||
type == NS_FORM_INPUT_EMAIL ||
|
||||
type == NS_FORM_INPUT_SEARCH ||
|
||||
type == NS_FORM_INPUT_TEL ||
|
||||
type == NS_FORM_INPUT_PASSWORD ||
|
||||
|
@ -81,6 +81,7 @@ enum ButtonElementTypes {
|
||||
enum InputElementTypes {
|
||||
NS_FORM_INPUT_BUTTON = NS_FORM_INPUT_ELEMENT + 1,
|
||||
NS_FORM_INPUT_CHECKBOX,
|
||||
NS_FORM_INPUT_EMAIL,
|
||||
NS_FORM_INPUT_FILE,
|
||||
NS_FORM_INPUT_HIDDEN,
|
||||
NS_FORM_INPUT_RESET,
|
||||
|
@ -81,6 +81,8 @@ nsConstraintValidation::GetValidationMessage(nsAString & aValidationMessage,
|
||||
GetValidationMessage(aValidationMessage, VALIDATION_MESSAGE_TOO_LONG);
|
||||
} else if (IsValueMissing()) {
|
||||
GetValidationMessage(aValidationMessage, VALIDATION_MESSAGE_VALUE_MISSING);
|
||||
} else if (HasTypeMismatch()) {
|
||||
GetValidationMessage(aValidationMessage, VALIDATION_MESSAGE_TYPE_MISMATCH);
|
||||
} else {
|
||||
// TODO: The other messages have not been written
|
||||
// because related constraint validation are not implemented yet.
|
||||
|
@ -2706,6 +2706,7 @@ nsGenericHTMLFormElement::IsSingleLineTextControlInternal(PRBool aExcludePasswor
|
||||
PRInt32 aType) const
|
||||
{
|
||||
return aType == NS_FORM_INPUT_TEXT ||
|
||||
aType == NS_FORM_INPUT_EMAIL ||
|
||||
aType == NS_FORM_INPUT_SEARCH ||
|
||||
aType == NS_FORM_INPUT_TEL ||
|
||||
(!aExcludePassword && aType == NS_FORM_INPUT_PASSWORD);
|
||||
|
@ -200,6 +200,7 @@ ShouldBeInElements(nsIFormControl* aFormControl)
|
||||
case NS_FORM_BUTTON_SUBMIT :
|
||||
case NS_FORM_INPUT_BUTTON :
|
||||
case NS_FORM_INPUT_CHECKBOX :
|
||||
case NS_FORM_INPUT_EMAIL :
|
||||
case NS_FORM_INPUT_FILE :
|
||||
case NS_FORM_INPUT_HIDDEN :
|
||||
case NS_FORM_INPUT_RESET :
|
||||
|
@ -107,6 +107,7 @@
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsHTMLFormElement.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
|
||||
#include "nsTextEditRules.h"
|
||||
|
||||
@ -133,6 +134,7 @@ static PRInt32 gSelectTextFieldOnFocus;
|
||||
static const nsAttrValue::EnumTable kInputTypeTable[] = {
|
||||
{ "button", NS_FORM_INPUT_BUTTON },
|
||||
{ "checkbox", NS_FORM_INPUT_CHECKBOX },
|
||||
{ "email", NS_FORM_INPUT_EMAIL },
|
||||
{ "file", NS_FORM_INPUT_FILE },
|
||||
{ "hidden", NS_FORM_INPUT_HIDDEN },
|
||||
{ "reset", NS_FORM_INPUT_RESET },
|
||||
@ -147,7 +149,7 @@ static const nsAttrValue::EnumTable kInputTypeTable[] = {
|
||||
};
|
||||
|
||||
// Default type is 'text'.
|
||||
static const nsAttrValue::EnumTable* kInputDefaultType = &kInputTypeTable[11];
|
||||
static const nsAttrValue::EnumTable* kInputDefaultType = &kInputTypeTable[12];
|
||||
|
||||
#define NS_INPUT_ELEMENT_STATE_IID \
|
||||
{ /* dc3b3d14-23e2-4479-b513-7b369343e3a0 */ \
|
||||
@ -319,6 +321,7 @@ nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
switch (mType) {
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
@ -452,6 +455,7 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
// If we are changing type from File/Text/Tel/Passwd to other input types
|
||||
// we need save the mValue into value attribute
|
||||
if (mInputData.mValue &&
|
||||
mType != NS_FORM_INPUT_EMAIL &&
|
||||
mType != NS_FORM_INPUT_TEXT &&
|
||||
mType != NS_FORM_INPUT_SEARCH &&
|
||||
mType != NS_FORM_INPUT_PASSWORD &&
|
||||
@ -1837,6 +1841,7 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
(keyEvent->keyCode == NS_VK_RETURN ||
|
||||
keyEvent->keyCode == NS_VK_ENTER) &&
|
||||
(mType == NS_FORM_INPUT_TEXT ||
|
||||
mType == NS_FORM_INPUT_EMAIL ||
|
||||
mType == NS_FORM_INPUT_SEARCH ||
|
||||
mType == NS_FORM_INPUT_PASSWORD ||
|
||||
mType == NS_FORM_INPUT_TEL ||
|
||||
@ -2390,6 +2395,7 @@ nsHTMLInputElement::SetDefaultValueAsValue()
|
||||
}
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
{
|
||||
@ -2426,6 +2432,7 @@ nsHTMLInputElement::Reset()
|
||||
break;
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
SetValueChanged(PR_FALSE);
|
||||
@ -2592,6 +2599,7 @@ nsHTMLInputElement::SaveState()
|
||||
// Never save passwords in session history
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
break;
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
@ -2730,6 +2738,7 @@ nsHTMLInputElement::RestoreState(nsPresState* aState)
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
@ -2983,6 +2992,7 @@ nsHTMLInputElement::GetValueMode() const
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
return VALUE_MODE_VALUE;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in GetValueMode()");
|
||||
@ -3025,6 +3035,7 @@ nsHTMLInputElement::DoesReadOnlyApply() const
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesReadOnlyApply()");
|
||||
@ -3058,6 +3069,7 @@ nsHTMLInputElement::DoesRequiredApply() const
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesRequiredApply()");
|
||||
@ -3125,6 +3137,25 @@ nsHTMLInputElement::IsValueMissing()
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::HasTypeMismatch()
|
||||
{
|
||||
if (mType == NS_FORM_INPUT_EMAIL) {
|
||||
nsAutoString value;
|
||||
NS_ENSURE_SUCCESS(GetValue(value), PR_FALSE);
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::multiple) ?
|
||||
!IsValidEmailAddressList(value) :
|
||||
!IsValidEmailAddress(value);
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::IsBarredFromConstraintValidation()
|
||||
{
|
||||
@ -3186,6 +3217,18 @@ nsHTMLInputElement::GetValidationMessage(nsAString& aValidationMessage,
|
||||
aValidationMessage = message;
|
||||
break;
|
||||
}
|
||||
case VALIDATION_MESSAGE_TYPE_MISMATCH:
|
||||
{
|
||||
NS_ASSERTION(mType == NS_FORM_INPUT_EMAIL,
|
||||
"Only email type can suffer from a type mismatch!");
|
||||
|
||||
nsXPIDLString message;
|
||||
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"ElementSuffersFromInvalidEmail",
|
||||
message);
|
||||
aValidationMessage = message;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rv = nsConstraintValidation::GetValidationMessage(aValidationMessage, aType);
|
||||
}
|
||||
@ -3193,6 +3236,84 @@ nsHTMLInputElement::GetValidationMessage(nsAString& aValidationMessage,
|
||||
return rv;
|
||||
}
|
||||
|
||||
//static
|
||||
PRBool
|
||||
nsHTMLInputElement::IsValidEmailAddressList(const nsAString& aValue)
|
||||
{
|
||||
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
|
||||
tokenizer(aValue, ',');
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
if (!IsValidEmailAddress(tokenizer.nextToken())) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return !tokenizer.lastTokenEndedWithSeparator();
|
||||
}
|
||||
|
||||
//static
|
||||
PRBool
|
||||
nsHTMLInputElement::IsValidEmailAddress(const nsAString& aValue)
|
||||
{
|
||||
PRUint32 i = 0;
|
||||
PRUint32 length = aValue.Length();
|
||||
|
||||
// If the email address is empty, begins with a '@' or ends with a '.',
|
||||
// we know it's invalid.
|
||||
if (length == 0 || aValue[0] == '@' || aValue[length-1] == '.') {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Parsing the username.
|
||||
for (; i < length && aValue[i] != '@'; ++i) {
|
||||
PRUnichar c = aValue[i];
|
||||
|
||||
// The username characters have to be in this list to be valid.
|
||||
if (!(nsCRT::IsAsciiAlpha(c) || nsCRT::IsAsciiDigit(c) ||
|
||||
c == '.' || c == '!' || c == '#' || c == '$' || c == '%' ||
|
||||
c == '&' || c == '\''|| c == '*' || c == '+' || c == '-' ||
|
||||
c == '/' || c == '=' || c == '?' || c == '^' || c == '_' ||
|
||||
c == '`' || c == '{' || c == '|' || c == '}' || c == '~' )) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// There is no domain name (or it's one-character long),
|
||||
// that's not a valid email address.
|
||||
if (++i >= length) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// The domain name can't begin with a dot.
|
||||
if (aValue[i] == '.') {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// The domain name must have at least one dot which can't follow another dot,
|
||||
// can't be the first nor the last domain name character.
|
||||
PRBool dotFound = PR_FALSE;
|
||||
|
||||
// Parsing the domain name.
|
||||
for (; i < length; ++i) {
|
||||
PRUnichar c = aValue[i];
|
||||
|
||||
if (c == '.') {
|
||||
dotFound = PR_TRUE;
|
||||
// A dot can't follow a dot.
|
||||
if (aValue[i-1] == '.') {
|
||||
return PR_FALSE;
|
||||
}
|
||||
} else if (!(nsCRT::IsAsciiAlpha(c) || nsCRT::IsAsciiDigit(c) ||
|
||||
c == '-')) {
|
||||
// The domain characters have to be in this list to be valid.
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return dotFound;
|
||||
}
|
||||
|
||||
//
|
||||
// Visitor classes
|
||||
//
|
||||
|
@ -214,6 +214,7 @@ public:
|
||||
// nsConstraintValidation
|
||||
PRBool IsTooLong();
|
||||
PRBool IsValueMissing();
|
||||
PRBool HasTypeMismatch();
|
||||
PRBool IsBarredFromConstraintValidation();
|
||||
nsresult GetValidationMessage(nsAString& aValidationMessage,
|
||||
ValidationMessageType aType);
|
||||
@ -246,6 +247,28 @@ protected:
|
||||
VALUE_MODE_FILENAME
|
||||
};
|
||||
|
||||
/**
|
||||
* This helper method returns true if aValue is a valid email address.
|
||||
* This is following the HTML5 specification:
|
||||
* http://dev.w3.org/html5/spec/forms.html#valid-e-mail-address
|
||||
*
|
||||
* @param aValue the email address to check.
|
||||
* @result whether the given string is a valid email address.
|
||||
*/
|
||||
static PRBool IsValidEmailAddress(const nsAString& aValue);
|
||||
|
||||
/**
|
||||
* This helper method returns true if aValue is a valid email address list.
|
||||
* Email address list is a list of email address separated by comas (,) which
|
||||
* can be surrounded by space charecters.
|
||||
* This is following the HTML5 specification:
|
||||
* http://dev.w3.org/html5/spec/forms.html#valid-e-mail-address-list
|
||||
*
|
||||
* @param aValue the email address list to check.
|
||||
* @result whether the given string is a valid email address list.
|
||||
*/
|
||||
static PRBool IsValidEmailAddressList(const nsAString& aValue);
|
||||
|
||||
// Helper method
|
||||
nsresult SetValueInternal(const nsAString& aValue,
|
||||
PRBool aUserInput,
|
||||
|
@ -195,6 +195,7 @@ _TEST_FILES = \
|
||||
test_bug345624-2.html \
|
||||
test_bug561640.html \
|
||||
test_bug345822.html \
|
||||
test_bug555559.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
@ -77,7 +77,7 @@ function checkSufferingFromBeingMissing(element)
|
||||
"You have to select one of these options.",
|
||||
"Validation message is wrong");
|
||||
}
|
||||
else if (input .type == 'file')
|
||||
else if (element.type == 'file')
|
||||
{
|
||||
is(element.validationMessage,
|
||||
"You have to select a file.",
|
||||
@ -143,7 +143,11 @@ function checkInputRequiredValidity(element)
|
||||
element.readOnly = false;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.value = 'foo';
|
||||
if (element.type == 'email') {
|
||||
element.value = 'foo@bar.com';
|
||||
} else {
|
||||
element.value = 'foo';
|
||||
}
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.value = '';
|
||||
@ -289,9 +293,8 @@ input.type = 'image';
|
||||
checkInputRequiredNotApply(input);
|
||||
|
||||
// Now, checking for all types which accept the required attribute.
|
||||
// TODO: check 'url', 'email', 'datetime', 'date',
|
||||
// 'month', 'week', 'time', 'datetime-local' and 'number'
|
||||
// when they will be implemented.
|
||||
// TODO: check 'url', 'datetime', 'date', 'month', 'week', 'time',
|
||||
// 'datetime-local' and 'number' when they will be implemented.
|
||||
input.type = 'text';
|
||||
checkInputRequiredValidity(input);
|
||||
input.type = 'password';
|
||||
@ -306,6 +309,8 @@ input.type = 'search';
|
||||
checkInputRequiredValidity(input);
|
||||
input.type = 'tel';
|
||||
checkInputRequiredValidity(input);
|
||||
input.type = 'email';
|
||||
checkInputRequiredValidity(input);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -84,6 +84,7 @@ checkType(document.getElementById('b1'), document.getElementById('b2'), 'submit'
|
||||
// input types
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'button', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'checkbox', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'email', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'file', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'hidden', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'reset', wrongType);
|
||||
|
244
content/html/content/test/test_bug555559.html
Normal file
244
content/html/content/test/test_bug555559.html
Normal file
@ -0,0 +1,244 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=555559
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 555559</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=555559">Mozilla Bug 555559</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<form>
|
||||
<input type='email' name='email' id='i' oninvalid="invalidEventHandler(event);">
|
||||
<form>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 555559 **/
|
||||
|
||||
// More checks are done in test_bug551670.html.
|
||||
|
||||
var gInvalid = false;
|
||||
|
||||
function invalidEventHandler(e)
|
||||
{
|
||||
is(e.type, "invalid", "Invalid event type should be invalid");
|
||||
gInvalid = true;
|
||||
}
|
||||
|
||||
function todoCheckValidEmailAddress(element)
|
||||
{
|
||||
gInvalid = false;
|
||||
todo(!element.validity.typeMismatch,
|
||||
"Element should not suffer from type mismatch");
|
||||
todo(element.validity.valid, "Element should be valid");
|
||||
todo(element.checkValidity(), "Element should be valid");
|
||||
todo(!gInvalid, "The invalid event should not have been thrown");
|
||||
todo_is(element.validationMessage, '',
|
||||
"Validation message should be the empty string");
|
||||
}
|
||||
|
||||
function checkValidEmailAddress(element)
|
||||
{
|
||||
gInvalid = false;
|
||||
ok(!element.validity.typeMismatch,
|
||||
"Element should not suffer from type mismatch");
|
||||
ok(element.validity.valid, "Element should be valid");
|
||||
ok(element.checkValidity(), "Element should be valid");
|
||||
ok(!gInvalid, "The invalid event should not have been thrown");
|
||||
is(element.validationMessage, '',
|
||||
"Validation message should be the empty string");
|
||||
}
|
||||
|
||||
function checkInvalidEmailAddress(element)
|
||||
{
|
||||
gInvalid = false;
|
||||
ok(element.validity.typeMismatch,
|
||||
"Element should suffer from type mismatch");
|
||||
ok(!element.validity.valid, "Element should not be valid");
|
||||
ok(!element.checkValidity(), "Element should not be valid");
|
||||
ok(gInvalid, "The invalid event should have been thrown");
|
||||
is(element.validationMessage, "The entered email address is not valid.",
|
||||
"Validation message is not valid");
|
||||
}
|
||||
|
||||
var email = document.forms[0].elements[0];
|
||||
is(email.type, 'email', "email state should be recognized");
|
||||
|
||||
// This is not really a valid email address
|
||||
// but it should not be considered as invalid.
|
||||
email.value = '';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = ' foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com ';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'tulip';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
// Some checks on the user part of the address.
|
||||
email.value = '@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
var legalCharacters = "abcdefghijklmnopqrstuvwxyz";
|
||||
legalCharacters += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
legalCharacters += "0123456789";
|
||||
legalCharacters += "!#$%&'*+-/=?^_`{|}~.";
|
||||
|
||||
for each (c in legalCharacters)
|
||||
{
|
||||
email.value = c + '@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
}
|
||||
|
||||
email.value = legalCharacters + '@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
// Checking stripped characters.
|
||||
email.value = 'f\noo@bar.com';
|
||||
todoCheckValidEmailAddress(email);
|
||||
|
||||
email.value = 'f\roo@bar.com';
|
||||
todoCheckValidEmailAddress(email);
|
||||
|
||||
// Testing some illegal characters.
|
||||
var illegalCharacters = "()<>[]:;@\, \t";
|
||||
|
||||
for each (c in illegalCharacters)
|
||||
{
|
||||
email.value = c + '@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
}
|
||||
|
||||
// Some checks on the domain part of the address.
|
||||
email.value = 'foo@bar';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@b';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@foo.bar';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@foo..bar';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@.bar';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@tulip.foo.bar';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@tulip.foo-bar';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@1.2';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@127.0.0.1';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@1.2.3.';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
// Checking stripped characters.
|
||||
email.value = 'foo@b\nar.com';
|
||||
todoCheckValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@b\rar.com';
|
||||
todoCheckValidEmailAddress(email);
|
||||
|
||||
// Testing some illegal characters.
|
||||
illegalCharacters = "()<>[]:;@\,!#$%&'*+/=?^_`{|}~ \t";
|
||||
|
||||
for each (c in illegalCharacters)
|
||||
{
|
||||
email.value = 'foo@foo.bar' + c;
|
||||
checkInvalidEmailAddress(email);
|
||||
}
|
||||
|
||||
// Testing multiple: we are not going to re-test email validity, just multiple.
|
||||
email.multiple = true;
|
||||
|
||||
email.value = 'foo@bar.com, foo@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com,foo@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com,foo@bar.com,foo@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = ' foo@bar.com , foo@bar.com ';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = '\tfoo@bar.com\t,\tfoo@bar.com\t';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = '\rfoo@bar.com\r,\rfoo@bar.com\r';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = '\nfoo@bar.com\n,\nfoo@bar.com\n';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = '\ffoo@bar.com\f,\ffoo@bar.com\f';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = '\t foo@bar.com\r,\nfoo@bar.com\f';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@b,ar.com,foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com,foo@bar.com,';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = ' foo@bar.com , foo@bar.com , ';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = ',foo@bar.com,foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = ',foo@bar.com,foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com,,,foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com;foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = '<foo@bar.com>, <foo@bar.com>';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar, foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com, foo';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo, foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -68,4 +68,5 @@ TextElementSuffersFromBeingMissing=This field is mandatory, you have to fill it.
|
||||
CheckboxElementSuffersFromBeingMissing=This checkbox is mandatory, you have to check it.
|
||||
RadioElementSuffersFromBeingMissing=You have to select one of these options.
|
||||
FileElementSuffersFromBeingMissing=You have to select a file.
|
||||
ElementSuffersFromInvalidEmail=The entered email address is not valid.
|
||||
|
||||
|
@ -216,6 +216,7 @@ EmbedContextMenuInfo::SetFormControlType(nsIDOMEventTarget *originalTarget)
|
||||
break;
|
||||
case NS_FORM_INPUT_SUBMIT:
|
||||
break;
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
|
@ -3349,6 +3349,7 @@ nsWebBrowserPersist::CloneNodeWithFixedUpAttributes(
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> outElt = do_QueryInterface(*aNodeOut);
|
||||
nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(*aNodeOut);
|
||||
switch (formControl->GetType()) {
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
|
@ -3651,6 +3651,7 @@ nsCSSFrameConstructor::FindInputData(nsIContent* aContent,
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_FILE, NS_NewFileControlFrame),
|
||||
SIMPLE_INT_CHAIN(NS_FORM_INPUT_IMAGE,
|
||||
nsCSSFrameConstructor::FindImgControlData),
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_EMAIL, NS_NewTextControlFrame),
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_SEARCH, NS_NewTextControlFrame),
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_TEXT, NS_NewTextControlFrame),
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_TEL, NS_NewTextControlFrame),
|
||||
|
7
layout/reftests/forms/input/email/input-email-1.html
Normal file
7
layout/reftests/forms/input/email/input-email-1.html
Normal file
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Test: input element in email state looks like in text state -->
|
||||
<body>
|
||||
<input type="email">
|
||||
</body>
|
||||
</html>
|
18
layout/reftests/forms/input/email/input-email-2.html
Normal file
18
layout/reftests/forms/input/email/input-email-2.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: input element in email state looks like in text state -->
|
||||
<script type="text/javascript">
|
||||
function setToEmail()
|
||||
{
|
||||
document.getElementById('i').type = 'email';
|
||||
}
|
||||
function disableReftestWait()
|
||||
{
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<body onload="setToEmail(); disableReftestWait();">
|
||||
<input type='checkbox' id='i'>
|
||||
</body>
|
||||
</html>
|
19
layout/reftests/forms/input/email/input-email-3.html
Normal file
19
layout/reftests/forms/input/email/input-email-3.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: when switching to another type, the input element should not look
|
||||
like an input email element -->
|
||||
<script type="text/javascript">
|
||||
function setToCheckbox()
|
||||
{
|
||||
document.getElementById('i').type='checkbox';
|
||||
}
|
||||
function disableReftestWait()
|
||||
{
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<body onload="setToCheckbox(); disableReftestWait();">
|
||||
<input type='email' id='i'>
|
||||
</body>
|
||||
</html>
|
6
layout/reftests/forms/input/email/input-email-ref.html
Normal file
6
layout/reftests/forms/input/email/input-email-ref.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="text">
|
||||
</body>
|
||||
</html>
|
3
layout/reftests/forms/input/email/reftest.list
Normal file
3
layout/reftests/forms/input/email/reftest.list
Normal file
@ -0,0 +1,3 @@
|
||||
== input-email-1.html input-email-ref.html
|
||||
== input-email-2.html input-email-ref.html
|
||||
!= input-email-3.html input-email-ref.html
|
@ -1,2 +1,3 @@
|
||||
include email/reftest.list
|
||||
include tel/reftest.list
|
||||
include search/reftest.list
|
||||
|
Loading…
Reference in New Issue
Block a user