Fix some problems of text field decoration
authortkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Apr 2012 05:07:53 +0000 (05:07 +0000)
committertkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Apr 2012 05:07:53 +0000 (05:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=82693

Reviewed by Dimitri Glazkov.

- Fix a problem that decorations are not removed when the input type is
changed.
- Add a comment to the 'willDetach' callback.

No new tests because the behavior changes are not visible yet.

* GNUMakefile.list.am: Add HTMLShadowElement.*.
* html/InputType.cpp:
(WebCore::InputType::destroyShadowSubtree):
Remove all of ShadowRoot contents, and add a <shadow> element to each of
them. We don't remove ShadowRoots from the tree because it's not
supported well.
* html/shadow/TextFieldDecorationElement.cpp:
(getDecorationRootAndDecoratedRoot): A helper function for decorate().
If the input element has a ShadowRoot with single <shadow> child, we
don't create new ShadowRoot and reuse it.
(WebCore::TextFieldDecorationElement::decorate):
Use getDecorationRootAndDecoratedRoot().
* html/shadow/TextFieldDecorationElement.h:
(TextFieldDecorator): Add a comment to willDetach().

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

Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/html/InputType.cpp
Source/WebCore/html/shadow/TextFieldDecorationElement.cpp
Source/WebCore/html/shadow/TextFieldDecorationElement.h

index c7639d9..3bfa157 100644 (file)
@@ -1,3 +1,31 @@
+2012-03-29  Kent Tamura  <tkent@chromium.org>
+
+        Fix some problems of text field decoration
+        https://bugs.webkit.org/show_bug.cgi?id=82693
+
+        Reviewed by Dimitri Glazkov.
+
+        - Fix a problem that decorations are not removed when the input type is
+        changed.
+        - Add a comment to the 'willDetach' callback.
+
+        No new tests because the behavior changes are not visible yet.
+
+        * GNUMakefile.list.am: Add HTMLShadowElement.*.
+        * html/InputType.cpp:
+        (WebCore::InputType::destroyShadowSubtree):
+        Remove all of ShadowRoot contents, and add a <shadow> element to each of
+        them. We don't remove ShadowRoots from the tree because it's not
+        supported well.
+        * html/shadow/TextFieldDecorationElement.cpp:
+        (getDecorationRootAndDecoratedRoot): A helper function for decorate().
+        If the input element has a ShadowRoot with single <shadow> child, we
+        don't create new ShadowRoot and reuse it.
+        (WebCore::TextFieldDecorationElement::decorate):
+        Use getDecorationRootAndDecoratedRoot().
+        * html/shadow/TextFieldDecorationElement.h:
+        (TextFieldDecorator): Add a comment to willDetach().
+
 2012-04-01  Li Yin  <li.yin@intel.com>
 
         [WebSocket]Reserved bits test case should cover both extension and no-extension scenarios
index a0854a3..192c546 100644 (file)
@@ -904,6 +904,7 @@ dom_binding_idls += \
        $(WebCore)/html/canvas/WebGLUniformLocation.idl \
        $(WebCore)/html/canvas/WebGLVertexArrayObjectOES.idl \
        $(WebCore)/html/shadow/HTMLContentElement.idl \
+       $(WebCore)/html/shadow/HTMLShadowElement.idl \
        $(WebCore)/html/track/TextTrack.idl \
        $(WebCore)/html/track/TextTrackCue.idl \
        $(WebCore)/html/track/TextTrackCueList.idl \
@@ -2475,6 +2476,8 @@ webcore_sources += \
        Source/WebCore/html/shadow/HTMLContentElement.h \
        Source/WebCore/html/shadow/HTMLContentSelector.cpp \
        Source/WebCore/html/shadow/HTMLContentSelector.h \
+       Source/WebCore/html/shadow/HTMLShadowElement.cpp \
+       Source/WebCore/html/shadow/HTMLShadowElement.h \
        Source/WebCore/html/shadow/InsertionPoint.cpp \
        Source/WebCore/html/shadow/InsertionPoint.h \
        Source/WebCore/html/shadow/MediaControls.cpp \
index 3e4898c..ee27346 100644 (file)
@@ -41,6 +41,7 @@
 #include "FormDataList.h"
 #include "HTMLFormElement.h"
 #include "HTMLInputElement.h"
+#include "HTMLShadowElement.h"
 #include "HiddenInputType.h"
 #include "ImageInputType.h"
 #include "KeyboardEvent.h"
@@ -70,6 +71,7 @@
 
 namespace WebCore {
 
+using namespace HTMLNames;
 using namespace std;
 
 typedef PassOwnPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement*);
@@ -382,8 +384,17 @@ void InputType::destroyShadowSubtree()
     if (!element()->hasShadowRoot())
         return;
 
-    if (ShadowRoot* root = element()->shadowTree()->oldestShadowRoot())
+    ShadowRoot* root = element()->shadowTree()->oldestShadowRoot();
+    ASSERT(root);
+    root->removeAllChildren();
+
+    // It's ok to clear contents of all other ShadowRoots because they must have
+    // been created by TextFieldDecorationElement, and we don't allow adding
+    // AuthorShadowRoot to HTMLInputElement.
+    while ((root = root->youngerShadowRoot())) {
         root->removeAllChildren();
+        root->appendChild(HTMLShadowElement::create(shadowTag, element()->document()));
+    }
 }
 
 double InputType::parseToDouble(const String&, double defaultValue) const
index 44715e4..0b00c95 100644 (file)
@@ -66,16 +66,35 @@ PassRefPtr<TextFieldDecorationElement> TextFieldDecorationElement::create(Docume
     return adoptRef(new TextFieldDecorationElement(document, decorator));
 }
 
+static inline void getDecorationRootAndDecoratedRoot(HTMLInputElement* input, ShadowRoot*& decorationRoot, ShadowRoot*& decoratedRoot)
+{
+    ShadowRoot* existingRoot = input->shadowTree()->youngestShadowRoot();
+    ShadowRoot* newRoot = 0;
+    while (existingRoot->childNodeCount() == 1 && existingRoot->firstChild()->hasTagName(shadowTag)) {
+        newRoot = existingRoot;
+        existingRoot = existingRoot->olderShadowRoot();
+        ASSERT(existingRoot);
+    }
+    if (newRoot)
+        newRoot->removeChild(newRoot->firstChild());
+    else
+        newRoot = ShadowRoot::create(input, ShadowRoot::CreatingUserAgentShadowRoot, ASSERT_NO_EXCEPTION).get();
+    decorationRoot = newRoot;
+    decoratedRoot = existingRoot;
+}
+
 void TextFieldDecorationElement::decorate(HTMLInputElement* input)
 {
     ASSERT(input);
-    ShadowRoot* existingRoot = input->shadowTree()->youngestShadowRoot();
-    RefPtr<ShadowRoot> newRoot = ShadowRoot::create(input, ShadowRoot::CreatingUserAgentShadowRoot, ASSERT_NO_EXCEPTION);
+    ShadowRoot* existingRoot;
+    ShadowRoot* decorationRoot;
+    getDecorationRootAndDecoratedRoot(input, decorationRoot, existingRoot);
+    ASSERT(decorationRoot);
+    ASSERT(existingRoot);
     RefPtr<HTMLDivElement> box = HTMLDivElement::create(input->document());
-    newRoot->appendChild(box);
+    decorationRoot->appendChild(box);
     box->setInlineStyleProperty(CSSPropertyDisplay, CSSValueWebkitBox);
     box->setInlineStyleProperty(CSSPropertyWebkitBoxAlign, CSSValueCenter);
-    ASSERT(existingRoot);
     ASSERT(existingRoot->childNodeCount() == 1);
     toHTMLElement(existingRoot->firstChild())->setInlineStyleProperty(CSSPropertyWebkitBoxFlex, 1.0, CSSPrimitiveValue::CSS_NUMBER);
     box->appendChild(HTMLShadowElement::create(HTMLNames::shadowTag, input->document()));
index 020f2a5..b34e7b5 100644 (file)
@@ -52,6 +52,9 @@ public:
     virtual CachedImage* imageForReadonlyState() = 0;
 
     virtual void handleClick(HTMLInputElement*) = 0;
+    // This function is called just before detaching the decoration. It must not
+    // call functions which updating state of the specified HTMLInputElement
+    // object.
     virtual void willDetach(HTMLInputElement*) = 0;
 
     virtual ~TextFieldDecorator();