Index: Source/core/html/EmailInputType.cpp |
diff --git a/Source/core/html/EmailInputType.cpp b/Source/core/html/EmailInputType.cpp |
deleted file mode 100644 |
index 90ae4bc62cb3d375e7e003cac26f81cb0159fe9d..0000000000000000000000000000000000000000 |
--- a/Source/core/html/EmailInputType.cpp |
+++ /dev/null |
@@ -1,281 +0,0 @@ |
-/* |
- * This file is part of the WebKit project. |
- * |
- * Copyright (C) 2009 Michelangelo De Simone <micdesim@gmail.com> |
- * Copyright (C) 2010 Google Inc. All rights reserved. |
- * |
- * This library is free software; you can redistribute it and/or |
- * modify it under the terms of the GNU Library General Public |
- * License as published by the Free Software Foundation; either |
- * version 2 of the License, or (at your option) any later version. |
- * |
- * This library is distributed in the hope that it will be useful, |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
- * Library General Public License for more details. |
- * |
- * You should have received a copy of the GNU Library General Public License |
- * along with this library; see the file COPYING.LIB. If not, write to |
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
- * Boston, MA 02110-1301, USA. |
- * |
- */ |
- |
-#include "config.h" |
-#include "core/html/EmailInputType.h" |
- |
-#include "core/html/HTMLInputElement.h" |
-#include "core/html/InputTypeNames.h" |
-#include "core/html/parser/HTMLParserIdioms.h" |
-#include "core/page/Chrome.h" |
-#include "core/page/ChromeClient.h" |
-#include "core/platform/text/PlatformLocale.h" |
-#include "core/platform/text/RegularExpression.h" |
-#include "public/platform/Platform.h" |
-#include "wtf/PassOwnPtr.h" |
-#include "wtf/text/StringBuilder.h" |
-#include <unicode/uidna.h> |
- |
-namespace WebCore { |
- |
-using WebKit::WebLocalizedString; |
- |
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address |
-static const char localPartCharacters[] = "abcdefghijklmnopqrstuvwxyz0123456789!#$%&'*+/=?^_`{|}~.-"; |
-static const char emailPattern[] = |
- "[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" // local part |
- "@" |
- "[a-z0-9-]+(\\.[a-z0-9-]+)*"; // domain part |
- |
-// RFC5321 says the maximum total length of a domain name is 255 octets. |
-static const size_t maximumDomainNameLength = 255; |
-static const int32_t idnaConversionOption = UIDNA_ALLOW_UNASSIGNED; |
- |
-static String convertEmailAddressToASCII(const String& address) |
-{ |
- if (address.containsOnlyASCII()) |
- return address; |
- |
- size_t atPosition = address.find('@'); |
- if (atPosition == kNotFound) |
- return address; |
- |
- UErrorCode error = U_ZERO_ERROR; |
- UChar domainNameBuffer[maximumDomainNameLength]; |
- int32_t domainNameLength = uidna_IDNToASCII(address.charactersWithNullTermination().data() + atPosition + 1, address.length() - atPosition - 1, domainNameBuffer, WTF_ARRAY_LENGTH(domainNameBuffer), idnaConversionOption, 0, &error); |
- if (error != U_ZERO_ERROR || domainNameLength <= 0) |
- return address; |
- |
- StringBuilder builder; |
- builder.append(address, 0, atPosition + 1); |
- builder.append(domainNameBuffer, domainNameLength); |
- return builder.toString(); |
-} |
- |
-String EmailInputType::convertEmailAddressToUnicode(const String& address) const |
-{ |
- if (!address.containsOnlyASCII()) |
- return address; |
- |
- size_t atPosition = address.find('@'); |
- if (atPosition == kNotFound) |
- return address; |
- |
- if (address.find("xn--", atPosition + 1) == kNotFound) |
- return address; |
- |
- if (!chrome()) |
- return address; |
- |
- String languages = chrome()->client().acceptLanguages(); |
- String unicodeHost = WebKit::Platform::current()->convertIDNToUnicode(address.substring(atPosition + 1), languages); |
- StringBuilder builder; |
- builder.append(address, 0, atPosition + 1); |
- builder.append(unicodeHost); |
- return builder.toString(); |
-} |
- |
-static bool isInvalidLocalPartCharacter(UChar ch) |
-{ |
- if (!isASCII(ch)) |
- return true; |
- DEFINE_STATIC_LOCAL(const String, validCharacters, (localPartCharacters)); |
- return validCharacters.find(toASCIILower(ch)) == kNotFound; |
-} |
- |
-static bool isInvalidDomainCharacter(UChar ch) |
-{ |
- if (!isASCII(ch)) |
- return true; |
- return !isASCIILower(ch) && !isASCIIUpper(ch) && !isASCIIDigit(ch) && ch != '.' && ch != '-'; |
-} |
- |
-static bool checkValidDotUsage(const String& domain) |
-{ |
- if (domain.isEmpty()) |
- return true; |
- if (domain[0] == '.' || domain[domain.length() - 1] == '.') |
- return false; |
- return domain.find("..") == kNotFound; |
-} |
- |
-static bool isValidEmailAddress(const String& address) |
-{ |
- int addressLength = address.length(); |
- if (!addressLength) |
- return false; |
- |
- DEFINE_STATIC_LOCAL(const RegularExpression, regExp, (emailPattern, TextCaseInsensitive)); |
- |
- int matchLength; |
- int matchOffset = regExp.match(address, 0, &matchLength); |
- |
- return !matchOffset && matchLength == addressLength; |
-} |
- |
-PassRefPtr<InputType> EmailInputType::create(HTMLInputElement* element) |
-{ |
- return adoptRef(new EmailInputType(element)); |
-} |
- |
-void EmailInputType::countUsage() |
-{ |
- observeFeatureIfVisible(UseCounter::InputTypeEmail); |
-} |
- |
-const AtomicString& EmailInputType::formControlType() const |
-{ |
- return InputTypeNames::email(); |
-} |
- |
-// The return value is an invalid email address string if the specified string |
-// contains an invalid email address. Otherwise, null string is returned. |
-// If an empty string is returned, it means empty address is specified. |
-// e.g. "foo@example.com,,bar@example.com" for multiple case. |
-String EmailInputType::findInvalidAddress(const String& value) const |
-{ |
- if (value.isEmpty()) |
- return String(); |
- if (!element()->multiple()) |
- return isValidEmailAddress(value) ? String() : value; |
- Vector<String> addresses; |
- value.split(',', true, addresses); |
- for (unsigned i = 0; i < addresses.size(); ++i) { |
- String stripped = stripLeadingAndTrailingHTMLSpaces(addresses[i]); |
- if (!isValidEmailAddress(stripped)) |
- return stripped; |
- } |
- return String(); |
-} |
- |
-bool EmailInputType::typeMismatchFor(const String& value) const |
-{ |
- return !findInvalidAddress(value).isNull(); |
-} |
- |
-bool EmailInputType::typeMismatch() const |
-{ |
- return typeMismatchFor(element()->value()); |
-} |
- |
-String EmailInputType::typeMismatchText() const |
-{ |
- String invalidAddress = findInvalidAddress(element()->value()); |
- ASSERT(!invalidAddress.isNull()); |
- if (invalidAddress.isEmpty()) |
- return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailEmpty); |
- String atSign = String("@"); |
- size_t atIndex = invalidAddress.find('@'); |
- if (atIndex == kNotFound) |
- return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailNoAtSign, atSign, invalidAddress); |
- // We check validity against an ASCII value because of difficulty to check |
- // invalid characters. However we should show Unicode value. |
- String unicodeAddress = convertEmailAddressToUnicode(invalidAddress); |
- String localPart = invalidAddress.left(atIndex); |
- String domain = invalidAddress.substring(atIndex + 1); |
- if (localPart.isEmpty()) |
- return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailEmptyLocal, atSign, unicodeAddress); |
- if (domain.isEmpty()) |
- return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailEmptyDomain, atSign, unicodeAddress); |
- size_t invalidCharIndex = localPart.find(isInvalidLocalPartCharacter); |
- if (invalidCharIndex != kNotFound) { |
- unsigned charLength = U_IS_LEAD(localPart[invalidCharIndex]) ? 2 : 1; |
- return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailInvalidLocal, atSign, localPart.substring(invalidCharIndex, charLength)); |
- } |
- invalidCharIndex = domain.find(isInvalidDomainCharacter); |
- if (invalidCharIndex != kNotFound) { |
- unsigned charLength = U_IS_LEAD(domain[invalidCharIndex]) ? 2 : 1; |
- return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailInvalidDomain, atSign, domain.substring(invalidCharIndex, charLength)); |
- } |
- if (!checkValidDotUsage(domain)) { |
- size_t atIndexInUnicode = unicodeAddress.find('@'); |
- ASSERT(atIndexInUnicode != kNotFound); |
- return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailInvalidDots, String("."), unicodeAddress.substring(atIndexInUnicode + 1)); |
- } |
- if (element()->multiple()) |
- return locale().queryString(WebLocalizedString::ValidationTypeMismatchForMultipleEmail); |
- return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmail); |
-} |
- |
-bool EmailInputType::isEmailField() const |
-{ |
- return true; |
-} |
- |
-bool EmailInputType::supportsSelectionAPI() const |
-{ |
- return false; |
-} |
- |
-String EmailInputType::sanitizeValue(const String& proposedValue) const |
-{ |
- String noLineBreakValue = proposedValue.removeCharacters(isHTMLLineBreak); |
- if (!element()->multiple()) |
- return stripLeadingAndTrailingHTMLSpaces(noLineBreakValue); |
- Vector<String> addresses; |
- noLineBreakValue.split(',', true, addresses); |
- StringBuilder strippedValue; |
- for (size_t i = 0; i < addresses.size(); ++i) { |
- if (i > 0) |
- strippedValue.append(","); |
- strippedValue.append(stripLeadingAndTrailingHTMLSpaces(addresses[i])); |
- } |
- return strippedValue.toString(); |
-} |
- |
-String EmailInputType::convertFromVisibleValue(const String& visibleValue) const |
-{ |
- String sanitizedValue = sanitizeValue(visibleValue); |
- if (!element()->multiple()) |
- return convertEmailAddressToASCII(sanitizedValue); |
- Vector<String> addresses; |
- sanitizedValue.split(',', true, addresses); |
- StringBuilder builder; |
- builder.reserveCapacity(sanitizedValue.length()); |
- for (size_t i = 0; i < addresses.size(); ++i) { |
- if (i > 0) |
- builder.append(","); |
- builder.append(convertEmailAddressToASCII(addresses[i])); |
- } |
- return builder.toString(); |
-} |
- |
-String EmailInputType::visibleValue() const |
-{ |
- String value = element()->value(); |
- if (!element()->multiple()) |
- return convertEmailAddressToUnicode(value); |
- |
- Vector<String> addresses; |
- value.split(',', true, addresses); |
- StringBuilder builder; |
- builder.reserveCapacity(value.length()); |
- for (size_t i = 0; i < addresses.size(); ++i) { |
- if (i > 0) |
- builder.append(","); |
- builder.append(convertEmailAddressToUnicode(addresses[i])); |
- } |
- return builder.toString(); |
-} |
- |
-} // namespace WebCore |