summaryrefslogtreecommitdiffstats
path: root/WebCore/wml
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/wml')
-rw-r--r--WebCore/wml/WMLAElement.cpp15
-rw-r--r--WebCore/wml/WMLFormControlElement.cpp20
-rw-r--r--WebCore/wml/WMLFormControlElement.h5
-rw-r--r--WebCore/wml/WMLGoElement.cpp2
-rw-r--r--WebCore/wml/WMLImageElement.cpp4
-rw-r--r--WebCore/wml/WMLImageLoader.cpp4
-rw-r--r--WebCore/wml/WMLInputElement.cpp225
-rw-r--r--WebCore/wml/WMLInputElement.h11
-rw-r--r--WebCore/wml/WMLInsertedLegendElement.cpp7
-rw-r--r--WebCore/wml/WMLInsertedLegendElement.h2
-rw-r--r--WebCore/wml/WMLOptGroupElement.cpp1
-rw-r--r--WebCore/wml/WMLOptionElement.cpp1
-rw-r--r--WebCore/wml/WMLTableElement.cpp2
13 files changed, 253 insertions, 46 deletions
diff --git a/WebCore/wml/WMLAElement.cpp b/WebCore/wml/WMLAElement.cpp
index 795c1fd..758be78 100644
--- a/WebCore/wml/WMLAElement.cpp
+++ b/WebCore/wml/WMLAElement.cpp
@@ -38,7 +38,7 @@
#include "HTMLNames.h"
#include "KeyboardEvent.h"
#include "MouseEvent.h"
-#include "RenderFlow.h"
+#include "RenderBox.h"
#include "WMLNames.h"
namespace WebCore {
@@ -101,15 +101,14 @@ bool WMLAElement::isKeyboardFocusable(KeyboardEvent* event) const
if (!document()->frame()->eventHandler()->tabsToLinks(event))
return false;
+ if (!renderer() || !renderer()->isBoxModelObject())
+ return false;
+
// Before calling absoluteRects, check for the common case where the renderer
- // or one of the continuations is non-empty, since this is a faster check and
- // almost always returns true.
- RenderBox* box = toRenderBox(renderer());
+ // is non-empty, since this is a faster check and almost always returns true.
+ RenderBoxModelObject* box = toRenderBoxModelObject(renderer());
if (!box->borderBoundingBox().isEmpty())
return true;
- for (RenderFlow* r = box->virtualContinuation(); r; r = r->continuation())
- if (!r->borderBoundingBox().isEmpty())
- return true;
Vector<IntRect> rects;
FloatPoint absPos = renderer()->localToAbsolute();
@@ -151,7 +150,7 @@ void WMLAElement::defaultEventHandler(Event* event)
if (!event->defaultPrevented() && document()->frame()) {
KURL url = document()->completeURL(parseURL(getAttribute(HTMLNames::hrefAttr)));
- document()->frame()->loader()->urlSelected(url, target(), event, false, true);
+ document()->frame()->loader()->urlSelected(url, target(), event, false, false, true);
}
event->setDefaultHandled();
diff --git a/WebCore/wml/WMLFormControlElement.cpp b/WebCore/wml/WMLFormControlElement.cpp
index 15c3f68..4e76cb8 100644
--- a/WebCore/wml/WMLFormControlElement.cpp
+++ b/WebCore/wml/WMLFormControlElement.cpp
@@ -23,6 +23,10 @@
#if ENABLE(WML)
#include "WMLFormControlElement.h"
+#include "RenderBox.h"
+#include "RenderObject.h"
+#include "RenderStyle.h"
+
namespace WebCore {
// WMLFormControlElement
@@ -36,6 +40,22 @@ WMLFormControlElement::~WMLFormControlElement()
{
}
+bool WMLFormControlElement::isFocusable() const
+{
+ if (!renderer() || !renderer()->isBox())
+ return false;
+
+ if (toRenderBox(renderer())->size().isEmpty())
+ return false;
+
+ if (RenderStyle* style = renderer()->style()) {
+ if (style->visibility() != VISIBLE)
+ return false;
+ }
+
+ return true;
+}
+
// WMLFormControlElementWithState
WMLFormControlElementWithState::WMLFormControlElementWithState(const QualifiedName& tagName, Document* document)
: WMLFormControlElement(tagName, document)
diff --git a/WebCore/wml/WMLFormControlElement.h b/WebCore/wml/WMLFormControlElement.h
index 8afb676..449e512 100644
--- a/WebCore/wml/WMLFormControlElement.h
+++ b/WebCore/wml/WMLFormControlElement.h
@@ -33,13 +33,18 @@ public:
WMLFormControlElement(const QualifiedName& tagName, Document* document);
virtual ~WMLFormControlElement();
+ virtual bool isEnabled() const { return true; }
virtual bool isFormControlElement() const { return true; }
+ virtual bool isReadOnlyControl() const { return false; }
+ virtual bool isTextControl() const { return false; }
virtual bool valueMatchesRenderer() const { return m_valueMatchesRenderer; }
virtual void setValueMatchesRenderer(bool b = true) { m_valueMatchesRenderer = b; }
virtual const AtomicString& name() const { return emptyAtom; }
+ virtual bool isFocusable() const;
+
private:
bool m_valueMatchesRenderer;
};
diff --git a/WebCore/wml/WMLGoElement.cpp b/WebCore/wml/WMLGoElement.cpp
index 3e5c8bd..603a71d 100644
--- a/WebCore/wml/WMLGoElement.cpp
+++ b/WebCore/wml/WMLGoElement.cpp
@@ -131,7 +131,7 @@ void WMLGoElement::executeTask(Event*)
request.setCachePolicy(ReloadIgnoringCacheData);
}
- loader->load(request);
+ loader->load(request, false);
}
void WMLGoElement::preparePOSTRequest(ResourceRequest& request, bool inSameDeck, const String& cacheControl)
diff --git a/WebCore/wml/WMLImageElement.cpp b/WebCore/wml/WMLImageElement.cpp
index 05ed9a0..39d103d 100644
--- a/WebCore/wml/WMLImageElement.cpp
+++ b/WebCore/wml/WMLImageElement.cpp
@@ -70,7 +70,7 @@ void WMLImageElement::parseMappedAttribute(MappedAttribute* attr)
if (attrName == HTMLNames::altAttr) {
if (renderer() && renderer()->isImage())
- static_cast<RenderImage*>(renderer())->updateAltText();
+ toRenderImage(renderer())->updateAltText();
} else if (attrName == HTMLNames::srcAttr || attrName == localsrcAttr)
m_imageLoader.updateFromElementIgnoringPreviousError();
else if (attrName == HTMLNames::widthAttr)
@@ -94,7 +94,7 @@ void WMLImageElement::attach()
WMLElement::attach();
if (renderer() && renderer()->isImage()) {
- RenderImage* imageObj = static_cast<RenderImage*>(renderer());
+ RenderImage* imageObj = toRenderImage(renderer());
if (imageObj->hasImage())
return;
diff --git a/WebCore/wml/WMLImageLoader.cpp b/WebCore/wml/WMLImageLoader.cpp
index a1a020d..c77b511 100644
--- a/WebCore/wml/WMLImageLoader.cpp
+++ b/WebCore/wml/WMLImageLoader.cpp
@@ -45,10 +45,6 @@ WMLImageLoader::~WMLImageLoader()
void WMLImageLoader::dispatchLoadEvent()
{
// WML doesn't fire any events.
- if (haveFiredLoadEvent())
- return;
-
- setHaveFiredLoadEvent(true);
}
String WMLImageLoader::sourceURI(const AtomicString& attr) const
diff --git a/WebCore/wml/WMLInputElement.cpp b/WebCore/wml/WMLInputElement.cpp
index 05da2a7..9a44013 100644
--- a/WebCore/wml/WMLInputElement.cpp
+++ b/WebCore/wml/WMLInputElement.cpp
@@ -23,7 +23,6 @@
#if ENABLE(WML)
#include "WMLInputElement.h"
-#include "Document.h"
#include "EventNames.h"
#include "FormDataList.h"
#include "Frame.h"
@@ -31,6 +30,9 @@
#include "KeyboardEvent.h"
#include "RenderTextControlSingleLine.h"
#include "TextEvent.h"
+#include "WMLDocument.h"
+#include "WMLNames.h"
+#include "WMLPageState.h"
namespace WebCore {
@@ -38,6 +40,8 @@ WMLInputElement::WMLInputElement(const QualifiedName& tagName, Document* doc)
: WMLFormControlElementWithState(tagName, doc)
, m_data(this, this)
, m_isPasswordField(false)
+ , m_isEmptyOk(false)
+ , m_numOfCharsAllowedByMask(0)
{
}
@@ -47,30 +51,20 @@ WMLInputElement::~WMLInputElement()
document()->unregisterForDocumentActivationCallbacks(this);
}
-static inline bool isInputFocusable(RenderObject* renderer)
+static const AtomicString& formatCodes()
{
- if (!renderer || !renderer->isBox())
- return false;
-
- if (toRenderBox(renderer)->size().isEmpty())
- return false;
-
- if (RenderStyle* style = renderer->style()) {
- if (style->visibility() != VISIBLE)
- return false;
- }
-
- return true;
+ DEFINE_STATIC_LOCAL(AtomicString, codes, ("AaNnXxMm"));
+ return codes;
}
bool WMLInputElement::isKeyboardFocusable(KeyboardEvent*) const
{
- return isInputFocusable(renderer());
+ return WMLFormControlElementWithState::isFocusable();
}
bool WMLInputElement::isMouseFocusable() const
{
- return isInputFocusable(renderer());
+ return WMLFormControlElementWithState::isFocusable();
}
void WMLInputElement::dispatchFocusEvent()
@@ -81,6 +75,18 @@ void WMLInputElement::dispatchFocusEvent()
void WMLInputElement::dispatchBlurEvent()
{
+ // Firstly check if it is allowed to leave this input field
+ String val = value();
+ if ((!m_isEmptyOk && val.isEmpty()) || !isConformedToInputMask(val)) {
+ updateFocusAppearance(true);
+ return;
+ }
+
+ // update the name variable of WML input elmenet
+ String nameVariable = name();
+ if (!nameVariable.isEmpty())
+ wmlPageStateForDocument(document())->storeVariable(nameVariable, val);
+
InputElement::dispatchBlurEvent(m_data, document());
WMLElement::dispatchBlurEvent();
}
@@ -168,7 +174,7 @@ void WMLInputElement::restoreState(const String& state)
void WMLInputElement::select()
{
- if (RenderTextControl* r = static_cast<RenderTextControl*>(renderer()))
+ if (RenderTextControl* r = toRenderTextControl(renderer()))
r->select();
}
@@ -194,12 +200,14 @@ void WMLInputElement::parseMappedAttribute(MappedAttribute* attr)
InputElement::parseMaxLengthAttribute(m_data, attr);
else if (attr->name() == HTMLNames::sizeAttr)
InputElement::parseSizeAttribute(m_data, attr);
+ else if (attr->name() == WMLNames::formatAttr)
+ m_formatMask = validateInputMask(parseValueForbiddingVariableReferences(attr->value()));
+ else if (attr->name() == WMLNames::emptyokAttr)
+ m_isEmptyOk = (attr->value() == "true");
else
WMLElement::parseMappedAttribute(attr);
// FIXME: Handle 'accesskey' attribute
- // FIXME: Handle 'format' attribute
- // FIXME: Handle 'emptyok' attribute
// FIXME: Handle 'tabindex' attribute
// FIXME: Handle 'title' attribute
}
@@ -226,6 +234,13 @@ void WMLInputElement::attach()
// on the renderer.
if (renderer())
renderer()->updateFromElement();
+
+ // FIXME: maybe this is not a good place to do this since it is possible
+ // to cause unexpected several times initialise of <input> if we force the
+ // node to be reattached. But placing it here can ensure the run-webkit-tests
+ // get expected result,i.e. multiple-times initialise is expected when making
+ // layout test for WMLInputElement
+ init();
}
void WMLInputElement::detach()
@@ -252,8 +267,14 @@ void WMLInputElement::defaultEventHandler(Event* evt)
{
bool clickDefaultFormButton = false;
- if (evt->type() == eventNames().textInputEvent && evt->isTextEvent() && static_cast<TextEvent*>(evt)->data() == "\n")
- clickDefaultFormButton = true;
+ if (evt->type() == eventNames().textInputEvent && evt->isTextEvent()) {
+ TextEvent* textEvent = static_cast<TextEvent*>(evt);
+ if (textEvent->data() == "\n")
+ clickDefaultFormButton = true;
+ else if (renderer() && !isConformedToInputMask(textEvent->data()[0], toRenderTextControl(renderer())->text().length() + 1))
+ // If the inputed char doesn't conform to the input mask, stop handling
+ return;
+ }
if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent() && focused() && document()->frame()
&& document()->frame()->doTextFieldCommandFromEvent(this, static_cast<KeyboardEvent*>(evt))) {
@@ -338,6 +359,168 @@ void WMLInputElement::didMoveToNewOwnerDocument()
WMLElement::didMoveToNewOwnerDocument();
}
+void WMLInputElement::init()
+{
+ String nameVariable = name();
+ String variableValue;
+ WMLPageState* pageSate = wmlPageStateForDocument(document());
+ ASSERT(pageSate);
+ if (!nameVariable.isEmpty())
+ variableValue = pageSate->getVariable(nameVariable);
+
+ if (variableValue.isEmpty() || !isConformedToInputMask(variableValue)) {
+ String val = value();
+ if (isConformedToInputMask(val))
+ variableValue = val;
+ else
+ variableValue = "";
+
+ pageSate->storeVariable(nameVariable, variableValue);
+ }
+ setValue(variableValue);
+
+ if (!hasAttribute(WMLNames::emptyokAttr)) {
+ if (m_formatMask.isEmpty() ||
+ // check if the format codes is just "*f"
+ (m_formatMask.length() == 2 && m_formatMask[0] == '*' && formatCodes().find(m_formatMask[1]) != -1))
+ m_isEmptyOk = true;
+ }
+}
+
+String WMLInputElement::validateInputMask(const String& inputMask)
+{
+ 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 == '*' || (WTF::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
+ m_numOfCharsAllowedByMask = maskLength;
+
+ if (escapeCharCount)
+ m_numOfCharsAllowedByMask -= escapeCharCount;
+
+ if (hasWildcard) {
+ formatCode = inputMask[maskLength - 2];
+ if (formatCode == '*')
+ m_numOfCharsAllowedByMask = m_data.maxLength();
+ else {
+ unsigned leftLen = String(&formatCode).toInt();
+ m_numOfCharsAllowedByMask = leftLen + m_numOfCharsAllowedByMask - 2;
+ }
+ }
+
+ return inputMask;
+}
+
+bool WMLInputElement::isConformedToInputMask(const String& inputChars)
+{
+ for (unsigned i = 0; i < inputChars.length(); ++i)
+ if (!isConformedToInputMask(inputChars[i], i + 1, false))
+ return false;
+
+ return true;
+}
+
+bool WMLInputElement::isConformedToInputMask(UChar inChar, unsigned inputCharCount, bool isUserInput)
+{
+ if (m_formatMask.isEmpty())
+ return true;
+
+ if (inputCharCount > m_numOfCharsAllowedByMask)
+ return false;
+
+ unsigned maskIndex = 0;
+ if (isUserInput) {
+ unsigned cursorPosition = 0;
+ if (renderer())
+ cursorPosition = toRenderTextControl(renderer())->selectionStart();
+ else
+ cursorPosition = m_data.cachedSelectionStart();
+
+ maskIndex = cursorPositionToMaskIndex(cursorPosition);
+ } else
+ maskIndex = cursorPositionToMaskIndex(inputCharCount - 1);
+
+ bool ok = true;
+ UChar mask = m_formatMask[maskIndex];
+ // match the inputed character with input mask
+ switch (mask) {
+ case 'A':
+ ok = !WTF::isASCIIDigit(inChar) && !WTF::isASCIILower(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'a':
+ ok = !WTF::isASCIIDigit(inChar) && !WTF::isASCIIUpper(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'N':
+ ok = WTF::isASCIIDigit(inChar);
+ break;
+ case 'n':
+ ok = !WTF::isASCIIAlpha(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'X':
+ ok = !WTF::isASCIILower(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'x':
+ ok = !WTF::isASCIIUpper(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'M':
+ ok = WTF::isASCIIPrintable(inChar);
+ break;
+ case 'm':
+ ok = WTF::isASCIIPrintable(inChar);
+ break;
+ default:
+ ok = (mask == inChar);
+ break;
+ }
+
+ return ok;
+}
+
+unsigned WMLInputElement::cursorPositionToMaskIndex(unsigned cursorPosition)
+{
+ UChar mask;
+ int index = -1;
+ do {
+ mask = m_formatMask[++index];
+ if (mask == '\\')
+ ++index;
+ else if (mask == '*' || (WTF::isASCIIDigit(mask) && mask != '0')) {
+ index = m_formatMask.length() - 1;
+ break;
+ }
+ } while (cursorPosition--);
+
+ return index;
+}
+
}
#endif
diff --git a/WebCore/wml/WMLInputElement.h b/WebCore/wml/WMLInputElement.h
index 2b913df..a2c904f 100644
--- a/WebCore/wml/WMLInputElement.h
+++ b/WebCore/wml/WMLInputElement.h
@@ -43,6 +43,7 @@ public:
virtual bool shouldUseInputMethod() const { return !m_isPasswordField; }
virtual bool isChecked() const { return false; }
+ virtual bool isAutofilled() const { return false; }
virtual bool isIndeterminate() const { return false; }
virtual bool isTextControl() const { return true; }
virtual bool isRadioButton() const { return false; }
@@ -86,9 +87,19 @@ public:
virtual void willMoveToNewOwnerDocument();
virtual void didMoveToNewOwnerDocument();
+ bool isConformedToInputMask(const String&);
+ bool isConformedToInputMask(UChar, unsigned, bool isUserInput = true);
+
private:
+ void init();
+ String validateInputMask(const String&);
+ unsigned cursorPositionToMaskIndex(unsigned);
+
InputElementData m_data;
bool m_isPasswordField;
+ bool m_isEmptyOk;
+ String m_formatMask;
+ unsigned m_numOfCharsAllowedByMask;
};
}
diff --git a/WebCore/wml/WMLInsertedLegendElement.cpp b/WebCore/wml/WMLInsertedLegendElement.cpp
index 7decd77..1464e71 100644
--- a/WebCore/wml/WMLInsertedLegendElement.cpp
+++ b/WebCore/wml/WMLInsertedLegendElement.cpp
@@ -23,8 +23,6 @@
#if ENABLE(WML)
#include "WMLInsertedLegendElement.h"
-#include "RenderLegend.h"
-
namespace WebCore {
WMLInsertedLegendElement::WMLInsertedLegendElement(const QualifiedName& tagName, Document* doc)
@@ -36,11 +34,6 @@ WMLInsertedLegendElement::~WMLInsertedLegendElement()
{
}
-RenderObject* WMLInsertedLegendElement::createRenderer(RenderArena* arena, RenderStyle*)
-{
- return new (arena) RenderLegend(this);
-}
-
}
#endif
diff --git a/WebCore/wml/WMLInsertedLegendElement.h b/WebCore/wml/WMLInsertedLegendElement.h
index d758487..73392ad 100644
--- a/WebCore/wml/WMLInsertedLegendElement.h
+++ b/WebCore/wml/WMLInsertedLegendElement.h
@@ -30,8 +30,6 @@ class WMLInsertedLegendElement : public WMLElement {
public:
WMLInsertedLegendElement(const QualifiedName& tagName, Document*);
virtual ~WMLInsertedLegendElement();
-
- virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
};
}
diff --git a/WebCore/wml/WMLOptGroupElement.cpp b/WebCore/wml/WMLOptGroupElement.cpp
index 6d2ed52..3658cf6 100644
--- a/WebCore/wml/WMLOptGroupElement.cpp
+++ b/WebCore/wml/WMLOptGroupElement.cpp
@@ -25,6 +25,7 @@
#include "Document.h"
#include "HTMLNames.h"
+#include "NodeRenderStyle.h"
#include "RenderStyle.h"
#include "WMLNames.h"
diff --git a/WebCore/wml/WMLOptionElement.cpp b/WebCore/wml/WMLOptionElement.cpp
index f5d6785..dd1466f 100644
--- a/WebCore/wml/WMLOptionElement.cpp
+++ b/WebCore/wml/WMLOptionElement.cpp
@@ -24,6 +24,7 @@
#include "WMLOptionElement.h"
#include "HTMLNames.h"
+#include "NodeRenderStyle.h"
#include "RenderStyle.h"
#include "WMLNames.h"
diff --git a/WebCore/wml/WMLTableElement.cpp b/WebCore/wml/WMLTableElement.cpp
index f241f46..a305f97 100644
--- a/WebCore/wml/WMLTableElement.cpp
+++ b/WebCore/wml/WMLTableElement.cpp
@@ -66,7 +66,7 @@ void WMLTableElement::parseMappedAttribute(MappedAttribute* attr)
// Spec: This required attribute specifies the number of columns for the table.
// The user agent must create a table with exactly the number of columns specified
- // by the attribute value. It is an error to specify a value of zero (“0”).
+ // by the attribute value. It is an error to specify a value of zero ("0")
if (!m_columns || !isNumber)
reportWMLError(document(), WMLErrorInvalidColumnsNumberInTable);
} else if (attr->name() == HTMLNames::alignAttr)