diff options
author | Feng Qian <> | 2009-04-10 18:11:29 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-04-10 18:11:29 -0700 |
commit | 8f72e70a9fd78eec56623b3a62e68f16b7b27e28 (patch) | |
tree | 181bf9a400c30a1bf34ea6d72560e8d00111d549 /WebCore/wml | |
parent | 7ed56f225e0ade046e1c2178977f72b2d896f196 (diff) | |
download | external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.zip external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.tar.gz external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.tar.bz2 |
AI 145796: Land the WebKit merge @r42026.
Automated import of CL 145796
Diffstat (limited to 'WebCore/wml')
-rw-r--r-- | WebCore/wml/WMLAElement.cpp | 15 | ||||
-rw-r--r-- | WebCore/wml/WMLFormControlElement.cpp | 20 | ||||
-rw-r--r-- | WebCore/wml/WMLFormControlElement.h | 5 | ||||
-rw-r--r-- | WebCore/wml/WMLGoElement.cpp | 2 | ||||
-rw-r--r-- | WebCore/wml/WMLImageElement.cpp | 4 | ||||
-rw-r--r-- | WebCore/wml/WMLImageLoader.cpp | 4 | ||||
-rw-r--r-- | WebCore/wml/WMLInputElement.cpp | 225 | ||||
-rw-r--r-- | WebCore/wml/WMLInputElement.h | 11 | ||||
-rw-r--r-- | WebCore/wml/WMLInsertedLegendElement.cpp | 7 | ||||
-rw-r--r-- | WebCore/wml/WMLInsertedLegendElement.h | 2 | ||||
-rw-r--r-- | WebCore/wml/WMLOptGroupElement.cpp | 1 | ||||
-rw-r--r-- | WebCore/wml/WMLOptionElement.cpp | 1 | ||||
-rw-r--r-- | WebCore/wml/WMLTableElement.cpp | 2 |
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) |