2010-05-05 Charles Wei <charles.wei@torchmobile.com.cn>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 May 2010 06:54:21 +0000 (06:54 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 May 2010 06:54:21 +0000 (06:54 +0000)
        Reviewed by George Staikos

        https://bugs.webkit.org/show_bug.cgi?id=37848
        Add test cases for -wap-input-format and -wap-input-required of WCSS

        * fast/wcss/wap-input-format-expected.txt: Added.
        * fast/wcss/wap-input-format.xhtml: Added.
        * fast/wcss/wap-input-required-expected.txt: Added.
        * fast/wcss/wap-input-required.xhtml: Added.
2010-05-05  Charles Wei  <charles.wei@torchmobile.com.cn>

        Reviewed by George Staikos

        https://bugs.webkit.org/show_bug.cgi?id=37848
        This patch adds WCSS -wap-input-format and -wap-input-required support to WebKit

        Tests: fast/wcss/wap-input-format.xhtml
               fast/wcss/wap-input-required.xhtml

        * css/CSSParser.cpp:
        (WebCore::CSSParser::parseValue):
        (WebCore::CSSParser::parseWCSSInputProperty):
        * css/CSSParser.h:
        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::applyProperty):
        * css/WCSSPropertyNames.in:
        * dom/InputElement.cpp:
        (WebCore::InputElement::sanitizeValue):
        (WebCore::InputElement::handleBeforeTextInsertedEvent):
        (WebCore::InputElementData::InputElementData):
        (WebCore::formatCodes):
        (WebCore::cursorPositionToMaskIndex):
        (WebCore::InputElement::isConformToInputMask):
        (WebCore::InputElement::validateInputMask):
        * dom/InputElement.h:
        (WebCore::InputElementData::inputFormatMask):
        (WebCore::InputElementData::setInputFormatMask):
        (WebCore::InputElementData::maxInputCharsAllowed):
        (WebCore::InputElementData::setMaxInputCharsAllowed):
        * html/HTMLInputElement.cpp:
        (WebCore::HTMLInputElement::setWapInputFormat):
        * html/HTMLInputElement.h:
        (WebCore::HTMLInputElement::data):
        * wml/WMLInputElement.h:
        (WebCore::WMLInputElement::data):
2010-05-05  Charles Wei  <charles.wei@torchmobile.com.cn>

        Reviewed by George Staikos

        This patch adds WCSS -wap-input-format and -wap-input-required support to WebKit
        Make the test cases in fast/wcss optionional only when  WCSS is enabled.

        https://bugs.webkit.org/show_bug.cgi?id=37848

        * Scripts/old-run-webkit-tests:
        * Scripts/webkitperl/features.pm:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@58867 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/wcss/wap-input-format-expected.txt [new file with mode: 0644]
LayoutTests/fast/wcss/wap-input-format.xhtml [new file with mode: 0644]
LayoutTests/fast/wcss/wap-input-required-expected.txt [new file with mode: 0644]
LayoutTests/fast/wcss/wap-input-required.xhtml [new file with mode: 0644]
WebCore/ChangeLog
WebCore/css/CSSParser.cpp
WebCore/css/CSSParser.h
WebCore/css/CSSStyleSelector.cpp
WebCore/css/WCSSPropertyNames.in
WebCore/dom/InputElement.cpp
WebCore/dom/InputElement.h
WebCore/html/HTMLInputElement.cpp
WebCore/html/HTMLInputElement.h
WebCore/wml/WMLInputElement.h
WebKitTools/ChangeLog
WebKitTools/Scripts/old-run-webkit-tests
WebKitTools/Scripts/webkitperl/features.pm

index bd1349c..b77df7b 100644 (file)
@@ -1,3 +1,15 @@
+2010-05-05  Charles Wei  <charles.wei@torchmobile.com.cn>
+
+        Reviewed by George Staikos
+
+        https://bugs.webkit.org/show_bug.cgi?id=37848
+        Add test cases for -wap-input-format and -wap-input-required of WCSS
+
+        * fast/wcss/wap-input-format-expected.txt: Added.
+        * fast/wcss/wap-input-format.xhtml: Added.
+        * fast/wcss/wap-input-required-expected.txt: Added.
+        * fast/wcss/wap-input-required.xhtml: Added.
+
 2010-05-05  Shinichiro Hamaji  <hamaji@chromium.org>
 
         Reviewed by Eric Seidel.
diff --git a/LayoutTests/fast/wcss/wap-input-format-expected.txt b/LayoutTests/fast/wcss/wap-input-format-expected.txt
new file mode 100644 (file)
index 0000000..bf1b486
--- /dev/null
@@ -0,0 +1,29 @@
+Assume the user input the following "AaBbCcDdEeFfGg123456!@#$%^,.;" to each of the input elements
+{-wap-input-format:"*A";} only takes upper letters, symbols, punctuations
+PASS domValueOf("star_upA") is "ABCDEFG!@#$%^,.;"
+PASS visibleValueOf("star_upA") is "ABCDEFG!@#$%^,.;"
+{-wap-input-format:"*a";} only takes lower letters, symbols, punctuations
+PASS domValueOf("star_lowa") is "abcdefg!@#$%^,.;"
+PASS visibleValueOf("star_lowa") is "abcdefg!@#$%^,.;"
+{-wap-input-format:"*N";} only takes numbers 
+PASS domValueOf("star_upN") is "123456"
+PASS visibleValueOf("star_upN") is "123456"
+{-wap-input-format:"*n";} only takes numbers , symbals and punctuations 
+PASS domValueOf("star_lown") is "123456!@#$%^,.;"
+PASS visibleValueOf("star_lown") is "123456!@#$%^,.;"
+{-wap-input-format:"*X";} takes upper letters,numbers,symbals and punctuations 
+PASS domValueOf("star_upX") is "ABCDEFG123456!@#$%^,.;"
+PASS visibleValueOf("star_upX") is "ABCDEFG123456!@#$%^,.;"
+{-wap-input-format:"*x";} takes lower letters,numbers,symbals and punctuations 
+PASS domValueOf("star_lowx") is "abcdefg123456!@#$%^,.;"
+PASS visibleValueOf("star_lowx") is "abcdefg123456!@#$%^,.;"
+{-wap-input-format:"*M";} takes any character 
+PASS domValueOf("star_upM") is "AaBbCcDdEeFfGg123456!@#$%^,.;"
+PASS visibleValueOf("star_upM") is "AaBbCcDdEeFfGg123456!@#$%^,.;"
+{-wap-input-format:"*m";} takes any character 
+PASS domValueOf("star_lowm") is "AaBbCcDdEeFfGg123456!@#$%^,.;"
+PASS visibleValueOf("star_lowm") is "AaBbCcDdEeFfGg123456!@#$%^,.;"
+{-wap-input-format:"3N";} takes 3 numbers 
+PASS domValueOf("three_N") is "123"
+PASS visibleValueOf("three_N") is "123"
+        
diff --git a/LayoutTests/fast/wcss/wap-input-format.xhtml b/LayoutTests/fast/wcss/wap-input-format.xhtml
new file mode 100644 (file)
index 0000000..51ee503
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version="1.0"?>
+<!DOCTYPE html PUBLIC "-//WAPFORUM/DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+
+<style type="text/css">
+.star_upA  {-wap-input-format: "*A" ; }    /* upper letter, symbol, punctuation,  NO number */
+.star_lowa {-wap-input-format: "*a" ; }    /* lower letter, symbol, punctuation,  NO number */
+.star_upN  {-wap-input-format: "*N" ; }    /* number only */
+.star_lown {-wap-input-format: "*n" ; }    /* number , symbol, punctuation, no letter */
+.star_upX  {-wap-input-format: "*X" ; }    /* upper letter, number, symbol, punctuation, no lower letter */
+.star_lowx {-wap-input-format: "*x" ; }    /* lower letter, number, symbol, punctuation, no upper letter */
+.star_upM  {-wap-input-format: "*M" ; }    /* anything, with upper as the default input */
+.star_lowm {-wap-input-format: "*m" ; }    /* anything, with lower as the default input */
+.three_N   {-wap-input-format: "3N" ; }    /* up to 3 digit number */
+
+</style>
+
+<script src="../js/resources/js-test-pre.js"></script>
+
+</head>
+
+<body>
+<p id="description"></p>
+<div id="console"></div>
+
+<input type="text" id="star_upA"  class="star_upA" />
+<input type="text" id="star_lowa" class="star_lowa" />
+<input type="text" id="star_upN"  class="star_upN" />
+<input type="text" id="star_lown" class="star_lown" />
+<input type="text" id="star_upX"  class="star_upX" />
+<input type="text" id="star_lowx" class="star_lowx" />
+<input type="text" id="star_upM"  class="star_upM" />
+<input type="text" id="star_lowm" class="star_lowm" />
+<input type="text" id="three_N"  class="three_N" />
+
+<script type="text/javascript">
+
+function domValueOf(id) {
+    return document.getElementById(id).value;
+}
+function visibleValueOf(id) {
+    var el = document.getElementById(id);
+    el.focus();
+    document.execCommand('SelectAll');
+    return document.getSelection().toString();
+}
+
+function inputKeys(str) {
+    if(!window.eventSender)
+        return;
+    for(i = 0; i != str.length; i++) {
+        eventSender.keyDown(str.charAt(i));
+    }
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+}
+
+var str = "AaBbCcDdEeFfGg123456!@#$%^,.;";
+
+debug("Assume the user input the following \"" + str + "\" to each of the input elements<br/><br/>");
+
+debug('<br/>{-wap-input-format:"*A";} only takes upper letters, symbols, punctuations<br/>');
+
+document.getElementById("star_upA").focus();
+inputKeys(str);
+shouldBe('domValueOf("star_upA")','"ABCDEFG!@#$%^,.;"');
+shouldBe('visibleValueOf("star_upA")','"ABCDEFG!@#$%^,.;"');
+
+debug('<br/>{-wap-input-format:"*a";} only takes lower letters, symbols, punctuations<br /><br />');
+document.getElementById("star_lowa").focus();
+inputKeys(str);
+shouldBe('domValueOf("star_lowa")', '"abcdefg!@#$%^,.;"');
+shouldBe('visibleValueOf("star_lowa")', '"abcdefg!@#$%^,.;"');
+
+debug('<br/>{-wap-input-format:"*N";} only takes numbers <br />');
+document.getElementById("star_upN").focus();
+inputKeys(str);
+shouldBe('domValueOf("star_upN")', '"123456"');
+shouldBe('visibleValueOf("star_upN")', '"123456"');
+
+debug('<br/>{-wap-input-format:"*n";} only takes numbers , symbals and punctuations <br />');
+document.getElementById("star_lown").focus();
+inputKeys(str);
+shouldBe('domValueOf("star_lown")', '"123456!@#$%^,.;"');
+shouldBe('visibleValueOf("star_lown")', '"123456!@#$%^,.;"');
+
+debug('<br/>{-wap-input-format:"*X";} takes upper letters,numbers,symbals and punctuations <br />');
+document.getElementById("star_upX").focus();
+inputKeys(str);
+shouldBe('domValueOf("star_upX")', '"ABCDEFG123456!@#$%^,.;"');
+shouldBe('visibleValueOf("star_upX")', '"ABCDEFG123456!@#$%^,.;"');
+
+debug('<br/>{-wap-input-format:"*x";} takes lower letters,numbers,symbals and punctuations <br />');
+document.getElementById("star_lowx").focus();
+inputKeys(str);
+shouldBe('domValueOf("star_lowx")', '"abcdefg123456!@#$%^,.;"');
+shouldBe('visibleValueOf("star_lowx")', '"abcdefg123456!@#$%^,.;"');
+
+debug('<br/>{-wap-input-format:"*M";} takes any character <br />');
+document.getElementById("star_upM").focus();
+inputKeys(str);
+shouldBe('domValueOf("star_upM")', '"AaBbCcDdEeFfGg123456!@#$%^,.;"');
+shouldBe('visibleValueOf("star_upM")', '"AaBbCcDdEeFfGg123456!@#$%^,.;"');
+
+debug('<br/>{-wap-input-format:"*m";} takes any character <br />');
+document.getElementById("star_lowm").focus();
+inputKeys(str);
+shouldBe('domValueOf("star_lowm")', '"AaBbCcDdEeFfGg123456!@#$%^,.;"');
+shouldBe('visibleValueOf("star_lowm")', '"AaBbCcDdEeFfGg123456!@#$%^,.;"');
+
+debug('<br/>{-wap-input-format:"3N";} takes 3 numbers <br />');
+document.getElementById("three_N").focus();
+inputKeys(str);
+shouldBe('domValueOf("three_N")', '"123"');
+shouldBe('visibleValueOf("three_N")', '"123"');
+
+
+</script>
+
+
+</body>
+</html>
diff --git a/LayoutTests/fast/wcss/wap-input-required-expected.txt b/LayoutTests/fast/wcss/wap-input-required-expected.txt
new file mode 100644 (file)
index 0000000..949e076
--- /dev/null
@@ -0,0 +1,4 @@
+There are three form control elements below, the first one is required and blank,validity.valueMissing should be true, the other two either don't have -wap-input-required applied, or the -wap-input-required indicates false, and are not required .
+
+  
+SUCCESS SUCCESS SUCCESS
diff --git a/LayoutTests/fast/wcss/wap-input-required.xhtml b/LayoutTests/fast/wcss/wap-input-required.xhtml
new file mode 100644 (file)
index 0000000..d1c210f
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!DOCTYPE html PUBLIC "-//WAPFORUM/DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+<title>required and basic valueMissing</title>
+
+</head>
+
+<body>
+<p>There are three form control elements below, the first one is required and blank,validity.valueMissing should be true, the other two either don't have -wap-input-required applied, or the -wap-input-required indicates false, and are not required .</p>
+<input name="required" style="-wap-input-required:true;" />
+<input name="not_specified" />
+<textarea name="not_required" style="-wap-input-required:false;"></textarea>
+<p id="console"> </p>
+
+<script language="JavaScript" type="text/javascript">
+function log(message) {
+    document.getElementById("console").innerHTML +=  message + "  \n";
+}
+
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+
+    v = document.getElementsByName("required");
+    log(v[0].validity.valueMissing  ? "SUCCESS" : "FAILURE");
+    v = document.getElementsByName("not_specified");
+    log((!v[0].validity.valueMissing) ? "SUCCESS" : "FAILURE");
+
+    v = document.getElementsByName("not_required");
+    log((!v[0].validity.valueMissing) ? "SUCCESS" : "FAILURE");
+
+</script>
+</body>
+</html>
index 2cb1f05..9c1ab9d 100644 (file)
@@ -1,3 +1,40 @@
+2010-05-05  Charles Wei  <charles.wei@torchmobile.com.cn>
+
+        Reviewed by George Staikos
+
+        https://bugs.webkit.org/show_bug.cgi?id=37848
+        This patch adds WCSS -wap-input-format and -wap-input-required support to WebKit
+
+        Tests: fast/wcss/wap-input-format.xhtml
+               fast/wcss/wap-input-required.xhtml
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseValue):
+        (WebCore::CSSParser::parseWCSSInputProperty):
+        * css/CSSParser.h:
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::applyProperty):
+        * css/WCSSPropertyNames.in:
+        * dom/InputElement.cpp:
+        (WebCore::InputElement::sanitizeValue):
+        (WebCore::InputElement::handleBeforeTextInsertedEvent):
+        (WebCore::InputElementData::InputElementData):
+        (WebCore::formatCodes):
+        (WebCore::cursorPositionToMaskIndex):
+        (WebCore::InputElement::isConformToInputMask):
+        (WebCore::InputElement::validateInputMask):
+        * dom/InputElement.h:
+        (WebCore::InputElementData::inputFormatMask):
+        (WebCore::InputElementData::setInputFormatMask):
+        (WebCore::InputElementData::maxInputCharsAllowed):
+        (WebCore::InputElementData::setMaxInputCharsAllowed):
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::setWapInputFormat):
+        * html/HTMLInputElement.h:
+        (WebCore::HTMLInputElement::data):
+        * wml/WMLInputElement.h:
+        (WebCore::WMLInputElement::data):
+
 2010-05-05  MORITA Hajime  <morrita@google.com>
 
         Reviewed by Darin Adler.
index d0d9e40..6f7cf12 100644 (file)
@@ -1702,6 +1702,15 @@ bool CSSParser::parseValue(int propId, bool important)
     case CSSPropertyTextUnderline:
     case CSSPropertyWebkitVariableDeclarationBlock:
         return false;
+#if ENABLE(WCSS)
+    case CSSPropertyWapInputFormat:
+        validPrimitive = true;
+        break;
+    case CSSPropertyWapInputRequired:
+        parsedValue = parseWCSSInputProperty();
+        break;
+#endif
+
 #if ENABLE(SVG)
     default:
         return parseSVGValue(propId, important);
@@ -1730,6 +1739,27 @@ bool CSSParser::parseValue(int propId, bool important)
     return false;
 }
 
+#if ENABLE(WCSS)
+PassRefPtr<CSSValue> CSSParser::parseWCSSInputProperty()
+{
+    RefPtr<CSSValue> parsedValue = 0;
+    CSSParserValue* value = m_valueList->current();
+    String inputProperty;
+    if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT)
+        inputProperty = String(value->string);
+
+    if (!inputProperty.isEmpty())
+       parsedValue = CSSPrimitiveValue::create(inputProperty, CSSPrimitiveValue::CSS_STRING);
+
+    while (m_valueList->next()) {
+    // pass all other values, if any. If we don't do this, 
+    // the parser will think that it's not done and won't process this property  
+    }
+
+    return parsedValue;
+}
+#endif
+
 void CSSParser::addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
 {
     if (lval) {
index 0bd0213..6e0354e 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
  * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 - 2010  Torch Mobile (Beijing) Co. Ltd. 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
@@ -139,6 +140,10 @@ namespace WebCore {
         PassRefPtr<CSSValue> parseSVGStrokeDasharray();
 #endif
 
+#if ENABLE(WCSS)
+        PassRefPtr<CSSValue> parseWCSSInputProperty();
+#endif
+
         // CSS3 Parsing Routines (for properties specific to CSS3)
         bool parseShadow(int propId, bool important);
         bool parseBorderImage(int propId, bool important, RefPtr<CSSValue>&);
index 916083b..12d44ee 100644 (file)
@@ -5331,6 +5331,23 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
     case CSSPropertyWebkitTextStroke:
     case CSSPropertyWebkitVariableDeclarationBlock:
         return;
+#if ENABLE(WCSS)
+    case CSSPropertyWapInputFormat:
+        if (primitiveValue && m_element->hasTagName(WebCore::inputTag)) {
+            String mask = primitiveValue->getStringValue();
+            static_cast<HTMLInputElement*>(m_element)->setWapInputFormat(mask);
+        }
+        return;
+
+    case CSSPropertyWapInputRequired:
+        if (primitiveValue && m_element->isFormControlElement()) {
+            HTMLFormControlElement* element = static_cast<HTMLFormControlElement*>(m_element);
+            bool required = primitiveValue->getStringValue() == "true";
+            element->setRequired(required);
+        }
+        return;
+#endif 
+
 #if ENABLE(SVG)
     default:
         // Try the SVG properties
index 704209f..66be83b 100644 (file)
@@ -1,3 +1,5 @@
+-wap-input-format
+-wap-input-required
 -wap-marquee-dir
 -wap-marquee-loop
 -wap-marquee-speed
index 2b9da92..3459906 100644 (file)
 #include "InputElement.h"
 
 #include "BeforeTextInsertedEvent.h"
+
+#if ENABLE(WCSS)
+#include "CSSPropertyNames.h"
+#include "CSSRule.h"
+#include "CSSRuleList.h"
+#include "CSSStyleRule.h"
+#include "CSSStyleSelector.h"
+#endif
+
 #include "Chrome.h"
 #include "ChromeClient.h"
 #include "Document.h"
@@ -138,6 +147,14 @@ void InputElement::setValueFromRenderer(InputElementData& data, InputElement* in
 
 String InputElement::sanitizeValue(const InputElement* inputElement, const String& proposedValue)
 {
+#if ENABLE(WCSS)
+    InputElementData data = const_cast<InputElement*>(inputElement)->data();
+    if (!isConformToInputMask(data, proposedValue)) {
+        if (isConformToInputMask(data, data.value()))
+            return data.value();
+        return String();
+    }
+#endif
     return InputElement::sanitizeUserInputValue(inputElement, proposedValue, s_maximumLength);
 }
 
@@ -187,6 +204,18 @@ void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputEl
 
     // Truncate the inserted text to avoid violating the maxLength and other constraints.
     BeforeTextInsertedEvent* textEvent = static_cast<BeforeTextInsertedEvent*>(event);
+#if ENABLE(WCSS)
+    RefPtr<Range> range = element->document()->frame()->selection()->selection().toNormalizedRange();
+    String candidateString = toRenderTextControlSingleLine(element->renderer())->text();
+    if (selectionLength)
+        candidateString.replace(range->startOffset(), range->endOffset(), textEvent->text());
+    else
+        candidateString.insert(textEvent->text(), range->startOffset());
+    if (!isConformToInputMask(inputElement->data(), candidateString)) {
+        textEvent->setText("");
+        return;
+      }
+#endif
     textEvent->setText(sanitizeUserInputValue(inputElement, textEvent->text(), appendableLength));
 }
 
@@ -238,6 +267,10 @@ InputElementData::InputElementData()
     , m_maxLength(InputElement::s_maximumLength)
     , m_cachedSelectionStart(-1)
     , m_cachedSelectionEnd(-1)
+#if ENABLE(WCSS)
+    , m_inputFormatMask("*m")
+    , m_maxInputCharsAllowed(InputElement::s_maximumLength)
+#endif
 {
 }
 
@@ -259,4 +292,137 @@ InputElement* toInputElement(Element* element)
     return 0;
 }
 
+#if ENABLE(WCSS)
+static inline const AtomicString& formatCodes()
+{
+    DEFINE_STATIC_LOCAL(AtomicString, codes, ("AaNnXxMm"));
+    return codes;
+}
+
+static unsigned cursorPositionToMaskIndex(const String& inputFormatMask, unsigned cursorPosition)
+{
+    UChar mask;
+    int index = -1;
+    do {
+        mask = inputFormatMask[++index];
+        if (mask == '\\')
+            ++index;
+        else if (mask == '*' || (isASCIIDigit(mask) && mask != '0')) {
+            index = inputFormatMask.length() - 1;
+            break;
+        }
+    } while (cursorPosition--);
+
+    return index;
+}
+
+bool InputElement::isConformToInputMask(const InputElementData& data, const String& inputChars)
+{
+    for (unsigned i = 0; i < inputChars.length(); ++i)
+        if (!isConformToInputMask(data, inputChars[i], i))
+            return false;
+    return true;
+}
+
+bool InputElement::isConformToInputMask(const InputElementData& data, UChar inChar, unsigned cursorPosition)
+{
+    String inputFormatMask = data.inputFormatMask();
+
+    if (inputFormatMask.isEmpty() || inputFormatMask == "*M" || inputFormatMask == "*m")
+        return true;
+
+    if (cursorPosition >= data.maxInputCharsAllowed())
+        return false;
+
+    unsigned maskIndex = cursorPositionToMaskIndex(inputFormatMask, cursorPosition);
+    bool ok = true;
+    UChar mask = inputFormatMask[maskIndex];
+    // Match the inputed character with input mask
+    switch (mask) {
+    case 'A':
+        ok = !isASCIIDigit(inChar) && !isASCIILower(inChar) && isASCIIPrintable(inChar);
+        break;
+    case 'a':
+        ok = !isASCIIDigit(inChar) && !isASCIIUpper(inChar) && isASCIIPrintable(inChar);
+        break;
+    case 'N':
+        ok = isASCIIDigit(inChar);
+        break;
+    case 'n':
+        ok = !isASCIIAlpha(inChar) && isASCIIPrintable(inChar);
+        break;
+    case 'X':
+        ok = !isASCIILower(inChar) && isASCIIPrintable(inChar);
+        break;
+    case 'x':
+        ok = !isASCIIUpper(inChar) && isASCIIPrintable(inChar);
+        break;
+    case 'M':
+    case 'm':
+        ok = isASCIIPrintable(inChar);
+        break;
+    default:
+        ok = (mask == inChar);
+        break;
+    }
+
+    return ok;
+}
+
+String InputElement::validateInputMask(InputElementData& data, String& inputMask)
+{
+    inputMask.replace("\\\\", "\\");
+
+    bool isValid = true;
+    bool hasWildcard = false;
+    unsigned escapeCharCount = 0;
+    unsigned maskLength = inputMask.length();
+    UChar formatCode;
+    for (unsigned i = 0; i < maskLength; ++i) {
+        formatCode = inputMask[i];
+        if (formatCodes().find(formatCode) == -1) {
+            if (formatCode == '*' || (isASCIIDigit(formatCode) && formatCode != '0')) {
+                // Validate codes which ends with '*f' or 'nf'
+                formatCode = inputMask[++i];
+                if ((i + 1 != maskLength) || formatCodes().find(formatCode) == -1) {
+                    isValid = false;
+                    break;
+                }
+                hasWildcard = true;
+            } else if (formatCode == '\\') {
+                // skip over the next mask character
+                ++i;
+                ++escapeCharCount;
+            } else {
+                isValid = false;
+                break;
+            }
+        }
+    }
+
+    if (!isValid)
+        return String();
+    // calculate the number of characters allowed to be entered by input mask
+    unsigned allowedLength = maskLength;
+    if (escapeCharCount)
+        allowedLength -= escapeCharCount;
+
+    if (hasWildcard) {
+        formatCode = inputMask[maskLength - 2];
+        if (formatCode == '*')
+            allowedLength = data.maxInputCharsAllowed();
+        else {
+            unsigned leftLen = String(&formatCode).toInt();
+            allowedLength = leftLen + allowedLength - 2;
+        }
+    }
+
+    if (allowedLength < data.maxInputCharsAllowed())
+        data.setMaxInputCharsAllowed(allowedLength);
+
+    return inputMask;
+}
+
+#endif
+
 }
index ae33b29..bdd5645 100644 (file)
@@ -58,6 +58,10 @@ public:
 
     virtual void cacheSelection(int start, int end) = 0;
     virtual void select() = 0;
+  
+#if ENABLE(WCSS)
+    virtual InputElementData data() const = 0; 
+#endif
 
     static const int s_maximumLength;
     static const int s_defaultSize;
@@ -80,6 +84,11 @@ protected:
     static void parseMaxLengthAttribute(InputElementData&, InputElement*, Element*, MappedAttribute*);
     static void updateValueIfNeeded(InputElementData&, InputElement*);
     static void notifyFormStateChanged(Element*);
+#if ENABLE(WCSS)
+    static bool isConformToInputMask(const InputElementData&, const String&);
+    static bool isConformToInputMask(const InputElementData&, UChar, unsigned);
+    static String validateInputMask(InputElementData&, String&);
+#endif
 };
 
 // HTML/WMLInputElement hold this struct as member variable
@@ -109,6 +118,15 @@ public:
     int cachedSelectionEnd() const { return m_cachedSelectionEnd; }
     void setCachedSelectionEnd(int value) { m_cachedSelectionEnd = value; }
 
+#if ENABLE(WCSS)
+    String inputFormatMask() const { return m_inputFormatMask; }
+    void setInputFormatMask(const String& mask) { m_inputFormatMask = mask; }
+    unsigned maxInputCharsAllowed() const { return m_maxInputCharsAllowed; }
+    void setMaxInputCharsAllowed(unsigned maxLength) { m_maxInputCharsAllowed = maxLength; }
+  
+#endif
+
 private:
     AtomicString m_name;
     String m_value;
@@ -117,6 +135,10 @@ private:
     int m_maxLength;
     int m_cachedSelectionStart;
     int m_cachedSelectionEnd;
+#if ENABLE(WCSS)
+    String m_inputFormatMask;
+    unsigned m_maxInputCharsAllowed;
+#endif
 };
 
 InputElement* toInputElement(Element*);
index 479ebf5..e499caa 100644 (file)
@@ -2758,4 +2758,15 @@ void HTMLInputElement::stepUpFromRenderer(int n)
     stepUp(n, ec);
 }
 
+#if ENABLE(WCSS)
+void HTMLInputElement::setWapInputFormat(String& mask)
+{
+    String validateMask = validateInputMask(m_data, mask);
+    if (!validateMask.isEmpty())
+        m_data.setInputFormatMask(validateMask);
+}
+#endif
+
+
+
 } // namespace
index dcb49d8..e717628 100644 (file)
@@ -267,6 +267,11 @@ public:
     // An instance pointed by the DateComponents* parameter will have parsed values and be
     // modified even if the parsing fails.  The DateComponents* parameter may be 0.
     static bool parseToDateComponents(InputType, const String&, DateComponents*);
+
+#if ENABLE(WCSS)
+    void setWapInputFormat(String& mask);
+    virtual InputElementData data() const { return m_data; }
+#endif
     
 protected:
     virtual void willMoveToNewOwnerDocument();
index eea633b..bd4e175 100644 (file)
@@ -88,6 +88,9 @@ public:
 
     bool isConformedToInputMask(const String&);
     bool isConformedToInputMask(UChar, unsigned, bool isUserInput = true);
+#if ENABLE(WCSS)
+    virtual InputElementData data() const { return m_data; }
+#endif
 
 private:
     friend class WMLCardElement;
index 51b1da3..dd0e61c 100644 (file)
@@ -1,3 +1,15 @@
+2010-05-05  Charles Wei  <charles.wei@torchmobile.com.cn>
+
+        Reviewed by George Staikos
+
+        This patch adds WCSS -wap-input-format and -wap-input-required support to WebKit
+        Make the test cases in fast/wcss optionional only when  WCSS is enabled.
+
+        https://bugs.webkit.org/show_bug.cgi?id=37848
+
+        * Scripts/old-run-webkit-tests:
+        * Scripts/webkitperl/features.pm:
+
 2010-05-05  Kent Tamura  <tkent@chromium.org>
 
         Reviewed by Eric Seidel.
index d5d7349..f845832 100755 (executable)
@@ -501,6 +501,10 @@ if (checkWebCoreFeatureSupport("WML", 0)) {
     $ignoredDirectories{'wml'} = 1;
 }
 
+if (!checkWebCoreFeatureSupport("WCSS", 0)) {
+    $ignoredDirectories{'fast/wcss'} = 1;
+}
+
 if (!checkWebCoreFeatureSupport("XHTMLMP", 0)) {
     $ignoredDirectories{'fast/xhtmlmp'} = 1;
 }
index 1f88022..7ca924b 100644 (file)
@@ -72,6 +72,7 @@ sub hasFeature($$)
         "3D Rendering" => "WebCoreHas3DRendering",
         "3D Canvas" => "WebGLShader",
         "WML" => "WMLElement",
+        "WCSS" => "parseWCSSInputProperty",
         "XHTMLMP" => "isXHTMLMPDocument",
     );
     my $symbolName = $symbolForFeature{$featureName};