Title: [111930] trunk/Source/WebCore
Revision
111930
Author
[email protected]
Date
2012-03-23 16:41:22 -0700 (Fri, 23 Mar 2012)

Log Message

Add TextFieldDecorator and TextFieldDecorationElement
https://bugs.webkit.org/show_bug.cgi?id=80580

Reviewed by Dimitri Glazkov.

These classes will be used to add a decoration icon to a text field
<input> from outside of WebCore. We have a plan to use them in Chromium
port. So this patch doesn't add TextFieldDecorationElement.{cpp,h} to
non-Chromium build files.

How it works:
When a shadow subtree for a text field is created, we ask ChromeClient
to decorate it. ChromeClient appends a TextFieldDecorationElement to the
existing shadow subtree or another shadow tree. A TextFieldDecorator is
associated to a TextFieldDecorationElement, and it provides decoration
icon images and a click handler.

No new tests. This patch won't make any behavior change for now.

* WebCore.gypi: Add TextFieldDecorationElement.cpp and TextFieldDecorationElement.h
* dom/Element.h:
(WebCore::Element::isTextFieldDecoration):
* html/TextFieldInputType.cpp:
(WebCore::TextFieldInputType::createShadowSubtree):
Calls ChromeClient::willAddTextFieldDecorationsTo() and addTextFieldDecorationsTo().
* html/shadow/TextFieldDecorationElement.cpp: Added.
(WebCore::TextFieldDecorator::~TextFieldDecorator):
(WebCore::TextFieldDecorationElement::TextFieldDecorationElement):
(WebCore::TextFieldDecorationElement::create):
(WebCore::TextFieldDecorationElement::isTextFieldDecoration):
(WebCore::TextFieldDecorationElement::updateImage):
(WebCore::TextFieldDecorationElement::customStyleForRenderer):
Sets the size to a square of the font-size.
(WebCore::TextFieldDecorationElement::createRenderer):
Always creates a RenderImage.
(WebCore::TextFieldDecorationElement::attach):
Sets an image for appropriate state.
(WebCore::TextFieldDecorationElement::isMouseFocusable):
(WebCore::TextFieldDecorationElement::defaultEventHandler):
Delegate a click event to the corresponding function of TextFieldDecorator.
* html/shadow/TextFieldDecorationElement.h: Added.
(TextFieldDecorator): Added.
(TextFieldDecorationElement): Added.
(WebCore::toTextFieldDecorationElement): Added.
* page/ChromeClient.h:
(WebCore::ChromeClient::willAddTextFieldDecorationsTo): Add an empty implementation.
(WebCore::ChromeClient::addTextFieldDecorationsTo): ditto.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (111929 => 111930)


--- trunk/Source/WebCore/ChangeLog	2012-03-23 23:31:49 UTC (rev 111929)
+++ trunk/Source/WebCore/ChangeLog	2012-03-23 23:41:22 UTC (rev 111930)
@@ -1,3 +1,53 @@
+2012-03-23  Kent Tamura  <[email protected]>
+
+        Add TextFieldDecorator and TextFieldDecorationElement
+        https://bugs.webkit.org/show_bug.cgi?id=80580
+
+        Reviewed by Dimitri Glazkov.
+
+        These classes will be used to add a decoration icon to a text field
+        <input> from outside of WebCore. We have a plan to use them in Chromium
+        port. So this patch doesn't add TextFieldDecorationElement.{cpp,h} to
+        non-Chromium build files.
+
+        How it works:
+        When a shadow subtree for a text field is created, we ask ChromeClient
+        to decorate it. ChromeClient appends a TextFieldDecorationElement to the
+        existing shadow subtree or another shadow tree. A TextFieldDecorator is
+        associated to a TextFieldDecorationElement, and it provides decoration
+        icon images and a click handler.
+
+        No new tests. This patch won't make any behavior change for now.
+
+        * WebCore.gypi: Add TextFieldDecorationElement.cpp and TextFieldDecorationElement.h
+        * dom/Element.h:
+        (WebCore::Element::isTextFieldDecoration):
+        * html/TextFieldInputType.cpp:
+        (WebCore::TextFieldInputType::createShadowSubtree):
+        Calls ChromeClient::willAddTextFieldDecorationsTo() and addTextFieldDecorationsTo().
+        * html/shadow/TextFieldDecorationElement.cpp: Added.
+        (WebCore::TextFieldDecorator::~TextFieldDecorator):
+        (WebCore::TextFieldDecorationElement::TextFieldDecorationElement):
+        (WebCore::TextFieldDecorationElement::create):
+        (WebCore::TextFieldDecorationElement::isTextFieldDecoration):
+        (WebCore::TextFieldDecorationElement::updateImage):
+        (WebCore::TextFieldDecorationElement::customStyleForRenderer):
+        Sets the size to a square of the font-size.
+        (WebCore::TextFieldDecorationElement::createRenderer):
+        Always creates a RenderImage.
+        (WebCore::TextFieldDecorationElement::attach):
+        Sets an image for appropriate state.
+        (WebCore::TextFieldDecorationElement::isMouseFocusable):
+        (WebCore::TextFieldDecorationElement::defaultEventHandler):
+        Delegate a click event to the corresponding function of TextFieldDecorator.
+        * html/shadow/TextFieldDecorationElement.h: Added.
+        (TextFieldDecorator): Added.
+        (TextFieldDecorationElement): Added.
+        (WebCore::toTextFieldDecorationElement): Added.
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::willAddTextFieldDecorationsTo): Add an empty implementation.
+        (WebCore::ChromeClient::addTextFieldDecorationsTo): ditto.
+
 2012-03-23  Adam Klein  <[email protected]>
 
         Match DOM4 spec with respect to DocumentFragment insertion

Modified: trunk/Source/WebCore/WebCore.gypi (111929 => 111930)


--- trunk/Source/WebCore/WebCore.gypi	2012-03-23 23:31:49 UTC (rev 111929)
+++ trunk/Source/WebCore/WebCore.gypi	2012-03-23 23:41:22 UTC (rev 111930)
@@ -5684,6 +5684,8 @@
             'html/shadow/SliderThumbElement.h',
             'html/shadow/TextControlInnerElements.cpp',
             'html/shadow/TextControlInnerElements.h',
+            'html/shadow/TextFieldDecorationElement.cpp',
+            'html/shadow/TextFieldDecorationElement.h',
             'html/track/LoadableTextTrack.cpp',
             'html/track/LoadableTextTrack.h',
             'html/track/TextTrack.cpp',

Modified: trunk/Source/WebCore/dom/Element.h (111929 => 111930)


--- trunk/Source/WebCore/dom/Element.h	2012-03-23 23:31:49 UTC (rev 111929)
+++ trunk/Source/WebCore/dom/Element.h	2012-03-23 23:41:22 UTC (rev 111930)
@@ -361,6 +361,7 @@
     virtual bool isInRange() const { return false; }
     virtual bool isOutOfRange() const { return false; }
     virtual bool isFrameElementBase() const { return false; }
+    virtual bool isTextFieldDecoration() const { return false; }
 
     virtual bool canContainRangeEndPoint() const { return true; }
 

Modified: trunk/Source/WebCore/html/TextFieldInputType.cpp (111929 => 111930)


--- trunk/Source/WebCore/html/TextFieldInputType.cpp	2012-03-23 23:31:49 UTC (rev 111929)
+++ trunk/Source/WebCore/html/TextFieldInputType.cpp	2012-03-23 23:41:22 UTC (rev 111930)
@@ -33,6 +33,8 @@
 #include "TextFieldInputType.h"
 
 #include "BeforeTextInsertedEvent.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
 #include "FormDataList.h"
 #include "Frame.h"
 #include "HTMLInputElement.h"
@@ -220,8 +222,10 @@
 
     Document* document = element()->document();
     RefPtr<RenderTheme> theme = document->page() ? document->page()->theme() : RenderTheme::defaultTheme();
+    ChromeClient* chromeClient = document->page() ? document->page()->chrome()->client() : 0;
     bool shouldHaveSpinButton = theme->shouldHaveSpinButton(element());
-    bool createsContainer = shouldHaveSpinButton || needsContainer();
+    bool shouldAddDecorations = chromeClient && chromeClient->willAddTextFieldDecorationsTo(element());
+    bool createsContainer = shouldHaveSpinButton || needsContainer() || shouldAddDecorations;
 
     ExceptionCode ec = 0;
     m_innerText = TextControlInnerTextElement::create(document);
@@ -251,6 +255,9 @@
         m_innerSpinButton = SpinButtonElement::create(document);
         m_container->appendChild(m_innerSpinButton, ec);
     }
+
+    if (shouldAddDecorations)
+        chromeClient->addTextFieldDecorationsTo(element());
 }
 
 HTMLElement* TextFieldInputType::containerElement() const

Added: trunk/Source/WebCore/html/shadow/TextFieldDecorationElement.cpp (0 => 111930)


--- trunk/Source/WebCore/html/shadow/TextFieldDecorationElement.cpp	                        (rev 0)
+++ trunk/Source/WebCore/html/shadow/TextFieldDecorationElement.cpp	2012-03-23 23:41:22 UTC (rev 111930)
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TextFieldDecorationElement.h"
+
+#include "Event.h"
+#include "HTMLInputElement.h"
+#include "RenderImage.h"
+
+namespace WebCore {
+
+// TextFieldDecorator ----------------------------------------------------------------
+
+TextFieldDecorator::~TextFieldDecorator()
+{
+}
+
+// TextFieldDecorationElement ----------------------------------------------------------------
+
+TextFieldDecorationElement::TextFieldDecorationElement(Document* document, TextFieldDecorator* decorator)
+    : HTMLDivElement(HTMLNames::divTag, document)
+    , m_textFieldDecorator(decorator)
+{
+    ASSERT(decorator);
+    setHasCustomStyleForRenderer();
+}
+
+PassRefPtr<TextFieldDecorationElement> TextFieldDecorationElement::create(Document* document, TextFieldDecorator* decorator)
+{
+    return adoptRef(new TextFieldDecorationElement(document, decorator));
+}
+
+bool TextFieldDecorationElement::isTextFieldDecoration() const
+{
+    return true;
+}
+
+void TextFieldDecorationElement::updateImage()
+{
+    if (!renderer() || !renderer()->isImage())
+        return;
+    RenderImageResource* resource = toRenderImage(renderer())->imageResource();
+    HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
+    CachedImage* image;
+    if (input->disabled())
+        image = m_textFieldDecorator->imageForDisabledState();
+    else if (input->readOnly())
+        image = m_textFieldDecorator->imageForReadonlyState();
+    else
+        image = m_textFieldDecorator->imageForNormalState();
+    ASSERT(image);
+    resource->setCachedImage(image);
+}
+
+PassRefPtr<RenderStyle> TextFieldDecorationElement::customStyleForRenderer()
+{
+    RefPtr<RenderStyle> style = RenderStyle::create();
+    RenderStyle* inputStyle = shadowAncestorNode()->renderStyle();
+    ASSERT(inputStyle);
+    style->setWidth(Length(inputStyle->fontSize(), Fixed));
+    style->setHeight(Length(inputStyle->fontSize(), Fixed));
+    updateImage();
+    return style.release();
+}
+
+RenderObject* TextFieldDecorationElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+    RenderImage* image = new (arena) RenderImage(this);
+    image->setImageResource(RenderImageResource::create());
+    return image;
+}
+
+void TextFieldDecorationElement::attach()
+{
+    HTMLDivElement::attach();
+    updateImage();
+}
+
+bool TextFieldDecorationElement::isMouseFocusable() const
+{
+    return false;
+}
+
+void TextFieldDecorationElement::defaultEventHandler(Event* event)
+{
+    RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
+    if (input->disabled() || input->readOnly() || !event->isMouseEvent()) {
+        if (!event->defaultHandled())
+            HTMLDivElement::defaultEventHandler(event);
+        return;
+    }
+
+    RefPtr<TextFieldDecorationElement> protector(this);
+    if (event->type() == eventNames().clickEvent) {
+        m_textFieldDecorator->handleClick(input.get());
+        event->setDefaultHandled();
+    }
+
+    if (!event->defaultHandled())
+        HTMLDivElement::defaultEventHandler(event);
+}
+
+} // namespace WebCore

Added: trunk/Source/WebCore/html/shadow/TextFieldDecorationElement.h (0 => 111930)


--- trunk/Source/WebCore/html/shadow/TextFieldDecorationElement.h	                        (rev 0)
+++ trunk/Source/WebCore/html/shadow/TextFieldDecorationElement.h	2012-03-23 23:41:22 UTC (rev 111930)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TextFieldDecorationElement_h
+#define TextFieldDecorationElement_h
+
+#include "HTMLDivElement.h"
+
+namespace WebCore {
+
+class CachedImage;
+class HTMLInputElement;
+
+// A TextFieldDecorator object must live until all of text fields which were
+// decorated by it die.
+class TextFieldDecorator {
+public:
+    // Returns true if this TextFieldDecorator wants to add a
+    // decoration to the specified text field.
+    virtual bool willAddDecorationTo(HTMLInputElement*) = 0;
+
+    // A TextFieldDecorator object should own the CachedImage objects.
+    virtual CachedImage* imageForNormalState() = 0;
+    virtual CachedImage* imageForDisabledState() = 0;
+    virtual CachedImage* imageForReadonlyState() = 0;
+
+    virtual void handleClick(HTMLInputElement*) = 0;
+
+    virtual ~TextFieldDecorator();
+};
+
+// A TextFieldDecorationElement object must be in a shadow tree of an
+// HTMLInputElement.
+class TextFieldDecorationElement : public HTMLDivElement {
+public:
+    static PassRefPtr<TextFieldDecorationElement> create(Document*, TextFieldDecorator*);
+    TextFieldDecorator* textFieldDecorator() { return m_textFieldDecorator; }
+
+private:
+    TextFieldDecorationElement(Document*, TextFieldDecorator*);
+    virtual bool isTextFieldDecoration() const OVERRIDE;
+    virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
+    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) OVERRIDE;
+    virtual void attach() OVERRIDE;
+    virtual bool isMouseFocusable() const OVERRIDE;
+    virtual void defaultEventHandler(Event*) OVERRIDE;
+
+    void updateImage();
+
+    TextFieldDecorator* m_textFieldDecorator;
+};
+
+inline TextFieldDecorationElement* toTextFieldDecorationElement(Node* node)
+{
+    ASSERT(node);
+    ASSERT(node->isElementNode());
+    ASSERT(static_cast<Element*>(node)->isTextFieldDecoration());
+    return static_cast<TextFieldDecorationElement*>(node);
+}
+
+}
+#endif

Modified: trunk/Source/WebCore/page/ChromeClient.h (111929 => 111930)


--- trunk/Source/WebCore/page/ChromeClient.h	2012-03-23 23:31:49 UTC (rev 111929)
+++ trunk/Source/WebCore/page/ChromeClient.h	2012-03-23 23:41:22 UTC (rev 111930)
@@ -53,6 +53,7 @@
     class Frame;
     class Geolocation;
     class GraphicsLayer;
+    class HTMLInputElement;
     class HitTestResult;
     class IntRect;
     class NavigationAction;
@@ -307,6 +308,13 @@
         virtual PagePopup* openPagePopup(PagePopupClient*, const IntRect& originBoundsInRootView) = 0;
         virtual void closePagePopup(PagePopup*) = 0;
 #endif
+        // This function is called whenever a text field <input> is
+        // created. The implementation should return true if it wants
+        // to do something in addTextFieldDecorationsTo().
+        // The argument is always non-0.
+        virtual bool willAddTextFieldDecorationsTo(HTMLInputElement*) { return false; }
+        // The argument is always non-0.
+        virtual void addTextFieldDecorationsTo(HTMLInputElement*) { }
 
         virtual void postAccessibilityNotification(AccessibilityObject*, AXObjectCache::AXNotification) { }
         
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to