Title: [125449] branches/safari-536.26-branch

Diff

Modified: branches/safari-536.26-branch/LayoutTests/ChangeLog (125448 => 125449)


--- branches/safari-536.26-branch/LayoutTests/ChangeLog	2012-08-13 21:06:29 UTC (rev 125448)
+++ branches/safari-536.26-branch/LayoutTests/ChangeLog	2012-08-13 21:09:48 UTC (rev 125449)
@@ -1,5 +1,21 @@
 2012-08-13  Lucas Forschler  <[email protected]>
 
+    Merge r118725.
+
+    2012-05-28  Kent Tamura  <[email protected]>
+
+            Fix a crash in HTMLFormControlElement::disabled().
+            https://bugs.webkit.org/show_bug.cgi?id=86534
+
+            Reviewed by Ryosuke Niwa.
+
+            Add a testcase to confirm <lagend> doesn't affect validation.
+
+            * fast/forms/datalist/datalist-child-validation-expected.txt:
+            * fast/forms/datalist/datalist-child-validation.html:
+
+2012-08-13  Lucas Forschler  <[email protected]>
+
     Merge r118721
 
     2012-05-28  Kent Tamura  <[email protected]>
@@ -10125,3 +10141,4 @@
         * ChangeLog-2012-04-23: Copied from LayoutTests/ChangeLog.
 
 .
+.

Modified: branches/safari-536.26-branch/LayoutTests/fast/forms/datalist/datalist-child-validation-expected.txt (125448 => 125449)


--- branches/safari-536.26-branch/LayoutTests/fast/forms/datalist/datalist-child-validation-expected.txt	2012-08-13 21:06:29 UTC (rev 125448)
+++ branches/safari-536.26-branch/LayoutTests/fast/forms/datalist/datalist-child-validation-expected.txt	2012-08-13 21:09:48 UTC (rev 125449)
@@ -9,6 +9,7 @@
 PASS e.willValidate is true
 PASS e.willValidate is true
 PASS document.querySelector(":invalid") is e
+PASS document.getElementById("inLegend").willValidate is false
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: branches/safari-536.26-branch/LayoutTests/fast/forms/datalist/datalist-child-validation.html (125448 => 125449)


--- branches/safari-536.26-branch/LayoutTests/fast/forms/datalist/datalist-child-validation.html	2012-08-13 21:06:29 UTC (rev 125448)
+++ branches/safari-536.26-branch/LayoutTests/fast/forms/datalist/datalist-child-validation.html	2012-08-13 21:09:48 UTC (rev 125449)
@@ -11,8 +11,12 @@
   <div id=w>
     <input type=text id=e required>
   </div>
+  <legend>
+    <input id="inLegend" required>
+  </legend>
 </datalist>
 
+
 <script>
 description('Test for child elements of a datalist element.');
 
@@ -28,6 +32,8 @@
 shouldBeTrue('e.willValidate');
 shouldBe('document.querySelector(":invalid")', 'e');
 
+shouldBeFalse('document.getElementById("inLegend").willValidate');
+
 </script>
 <script src=""
 </body>

Modified: branches/safari-536.26-branch/Source/WebCore/ChangeLog (125448 => 125449)


--- branches/safari-536.26-branch/Source/WebCore/ChangeLog	2012-08-13 21:06:29 UTC (rev 125448)
+++ branches/safari-536.26-branch/Source/WebCore/ChangeLog	2012-08-13 21:09:48 UTC (rev 125449)
@@ -1,5 +1,61 @@
 2012-08-13  Lucas Forschler  <[email protected]>
 
+    Merge r118725.
+
+    2012-05-28  Kent Tamura  <[email protected]>
+
+            Fix a crash in HTMLFormControlElement::disabled().
+            https://bugs.webkit.org/show_bug.cgi?id=86534
+
+            Reviewed by Ryosuke Niwa.
+
+            Stop to hold pointers of fildset and legend elements. We can avoid it by
+            holding ancestor's disabled state.
+
+            The ancesotr's disabled state should be invalidated when
+             - fieldset's disabled value is changed.
+             - fieldset's children is updated because a legend position might be changed.
+             - A form control is attached to or detached from a tree.
+
+            No new tests. It's almost impossible to make a reliable test.
+
+            * html/HTMLFieldSetElement.cpp:
+            (WebCore::HTMLFieldSetElement::invalidateDisabledStateUnder):
+            Added. Invalidate disabled state of form controls under the specified node.
+            (WebCore::HTMLFieldSetElement::disabledAttributeChanged):
+            Uses invalidateDisabledStateUnder().
+            (WebCore::HTMLFieldSetElement::childrenChanged):
+            Added new override function. We need invalidate disabled state of form
+            controls under legend elements.
+
+            * html/HTMLFieldSetElement.h:
+            (HTMLFieldSetElement): Add invalidateDisabledStateUnder() and childrenChanged().
+
+            * html/HTMLFormControlElement.cpp:
+            (WebCore::HTMLFormControlElement::HTMLFormControlElement):
+            Remove initialization of the removed data members.
+            Initialize m_ancestorDisabledState.
+            (WebCore::HTMLFormControlElement::updateAncestorDisabledState):
+            Update m_ancestorDisabledState. It should be
+            AncestorDisabledStateDisabled if the control is under a disabled
+            fieldset and not under the first legend child of the disabled filedset.
+            (WebCore::HTMLFormControlElement::ancestorDisabledStateWasChanged):
+            Invalidate m_ancestorDisabledState.
+            (WebCore::HTMLFormControlElement::insertedInto): ditto.
+            (WebCore::HTMLFormControlElement::removedFrom): ditto.
+            (WebCore::HTMLFormControlElement::disabled):
+            Calls updateAncestorDisabledState() if needed.
+            (WebCore::HTMLFormControlElement::recalcWillValidate):
+            Remove unnecessary check for m_legendAncestor.
+
+            * html/HTMLFormControlElement.h:
+            (HTMLFormControlElement):
+            - Rename updateFieldSetAndLegendAncestor() to updateAncestorDisabledState(), and make it private.
+            - Remove m_fieldSetAncestor, m_legendAncestor, and m_fieldSetAncestorValid.
+            - Add m_ancestorDisabledState.
+
+2012-08-13  Lucas Forschler  <[email protected]>
+
     Merge r118721
 
     2012-05-28  Kent Tamura  <[email protected]>
@@ -205066,3 +205122,4 @@
 
 == Rolled over to ChangeLog-2011-10-19 ==
 .
+.

Modified: branches/safari-536.26-branch/Source/WebCore/html/HTMLFieldSetElement.cpp (125448 => 125449)


--- branches/safari-536.26-branch/Source/WebCore/html/HTMLFieldSetElement.cpp	2012-08-13 21:06:29 UTC (rev 125448)
+++ branches/safari-536.26-branch/Source/WebCore/html/HTMLFieldSetElement.cpp	2012-08-13 21:09:48 UTC (rev 125449)
@@ -45,14 +45,27 @@
     return adoptRef(new HTMLFieldSetElement(tagName, document, form));
 }
 
+void HTMLFieldSetElement::invalidateDisabledStateUnder(Element* base)
+{
+    for (Node* currentNode = base->traverseNextNode(base); currentNode; currentNode = currentNode->traverseNextNode(base)) {
+        if (currentNode && currentNode->isElementNode() && toElement(currentNode)->isFormControlElement())
+            static_cast<HTMLFormControlElement*>(currentNode)->ancestorDisabledStateWasChanged();
+    }
+}
+
 void HTMLFieldSetElement::disabledAttributeChanged()
 {
     // This element must be updated before the style of nodes in its subtree gets recalculated.
     HTMLFormControlElement::disabledAttributeChanged();
+    invalidateDisabledStateUnder(this);
+}
 
-    for (Node* currentNode = this->traverseNextNode(this); currentNode; currentNode = currentNode->traverseNextNode(this)) {
-        if (currentNode && currentNode->isElementNode() && toElement(currentNode)->isFormControlElement())
-            static_cast<HTMLFormControlElement*>(currentNode)->ancestorDisabledStateWasChanged();
+void HTMLFieldSetElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+    HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+    for (Element* element = firstElementChild(); element; element = element->nextElementSibling()) {
+        if (element->hasTagName(legendTag))
+            invalidateDisabledStateUnder(element);
     }
 }
 

Modified: branches/safari-536.26-branch/Source/WebCore/html/HTMLFieldSetElement.h (125448 => 125449)


--- branches/safari-536.26-branch/Source/WebCore/html/HTMLFieldSetElement.h	2012-08-13 21:06:29 UTC (rev 125448)
+++ branches/safari-536.26-branch/Source/WebCore/html/HTMLFieldSetElement.h	2012-08-13 21:09:48 UTC (rev 125449)
@@ -44,6 +44,9 @@
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     virtual const AtomicString& formControlType() const;
     virtual bool recalcWillValidate() const { return false; }
+    virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
+
+    static void invalidateDisabledStateUnder(Element*);
 };
 
 } // namespace

Modified: branches/safari-536.26-branch/Source/WebCore/html/HTMLFormControlElement.cpp (125448 => 125449)


--- branches/safari-536.26-branch/Source/WebCore/html/HTMLFormControlElement.cpp	2012-08-13 21:06:29 UTC (rev 125448)
+++ branches/safari-536.26-branch/Source/WebCore/html/HTMLFormControlElement.cpp	2012-08-13 21:09:48 UTC (rev 125449)
@@ -48,13 +48,11 @@
 
 HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
     : LabelableElement(tagName, document)
-    , m_fieldSetAncestor(0)
-    , m_legendAncestor(0)
-    , m_fieldSetAncestorValid(false)
     , m_disabled(false)
     , m_readOnly(false)
     , m_required(false)
     , m_valueMatchesRenderer(false)
+    , m_ancestorDisabledState(AncestorDisabledStateUnknown)
     , m_dataListAncestorState(Unknown)
     , m_willValidateInitialized(false)
     , m_willValidate(true)
@@ -101,23 +99,24 @@
     return fastHasAttribute(formnovalidateAttr);
 }
 
-void HTMLFormControlElement::updateFieldSetAndLegendAncestor() const
+void HTMLFormControlElement::updateAncestorDisabledState() const
 {
-    m_fieldSetAncestor = 0;
-    m_legendAncestor = 0;
+    HTMLFieldSetElement* fieldSetAncestor = 0;
+    ContainerNode* legendAncestor = 0;
     for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
-        if (!m_legendAncestor && ancestor->hasTagName(legendTag))
-            m_legendAncestor = static_cast<HTMLLegendElement*>(ancestor);
+        if (!legendAncestor && ancestor->hasTagName(legendTag))
+            legendAncestor = ancestor;
         if (ancestor->hasTagName(fieldsetTag)) {
-            m_fieldSetAncestor = static_cast<HTMLFieldSetElement*>(ancestor);
+            fieldSetAncestor = static_cast<HTMLFieldSetElement*>(ancestor);
             break;
         }
     }
-    m_fieldSetAncestorValid = true;
+    m_ancestorDisabledState = (fieldSetAncestor && fieldSetAncestor->disabled() && !(legendAncestor && legendAncestor == fieldSetAncestor->legend())) ? AncestorDisabledStateDisabled : AncestorDisabledStateEnabled;
 }
 
 void HTMLFormControlElement::ancestorDisabledStateWasChanged()
 {
+    m_ancestorDisabledState = AncestorDisabledStateUnknown;
     disabledAttributeChanged();
 }
 
@@ -230,7 +229,7 @@
 
 Node::InsertionNotificationRequest HTMLFormControlElement::insertedInto(Node* insertionPoint)
 {
-    m_fieldSetAncestorValid = false;
+    m_ancestorDisabledState = AncestorDisabledStateUnknown;
     m_dataListAncestorState = Unknown;
     setNeedsWillValidateCheck();
     HTMLElement::insertedInto(insertionPoint);
@@ -240,7 +239,7 @@
 
 void HTMLFormControlElement::removedFrom(Node* insertionPoint)
 {
-    m_fieldSetAncestorValid = false;
+    m_ancestorDisabledState = AncestorDisabledStateUnknown;
     m_dataListAncestorState = Unknown;
     HTMLElement::removedFrom(insertionPoint);
     FormAssociatedElement::removedFrom(insertionPoint);
@@ -284,13 +283,9 @@
     if (m_disabled)
         return true;
 
-    if (!m_fieldSetAncestorValid)
-        updateFieldSetAndLegendAncestor();
-
-    // Form controls in the first legend element inside a fieldset are not affected by fieldset.disabled.
-    if (m_fieldSetAncestor && m_fieldSetAncestor->disabled())
-        return !(m_legendAncestor && m_legendAncestor == m_fieldSetAncestor->legend());
-    return false;
+    if (m_ancestorDisabledState == AncestorDisabledStateUnknown)
+        updateAncestorDisabledState();
+    return m_ancestorDisabledState == AncestorDisabledStateDisabled;
 }
 
 void HTMLFormControlElement::setDisabled(bool b)
@@ -366,7 +361,7 @@
 {
     if (m_dataListAncestorState == Unknown) {
         for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
-            if (!m_legendAncestor && ancestor->hasTagName(datalistTag)) {
+            if (ancestor->hasTagName(datalistTag)) {
                 m_dataListAncestorState = InsideDataList;
                 break;
             }

Modified: branches/safari-536.26-branch/Source/WebCore/html/HTMLFormControlElement.h (125448 => 125449)


--- branches/safari-536.26-branch/Source/WebCore/html/HTMLFormControlElement.h	2012-08-13 21:06:29 UTC (rev 125448)
+++ branches/safari-536.26-branch/Source/WebCore/html/HTMLFormControlElement.h	2012-08-13 21:09:48 UTC (rev 125449)
@@ -51,7 +51,6 @@
     void setFormMethod(const String&);
     bool formNoValidate() const;
 
-    void updateFieldSetAndLegendAncestor() const;
     void ancestorDisabledStateWasChanged();
 
     virtual void reset() { }
@@ -152,16 +151,16 @@
     virtual bool isDefaultButtonForForm() const;
     virtual bool isValidFormControlElement();
     String visibleValidationMessage() const;
+    void updateAncestorDisabledState() const;
 
-    mutable HTMLFieldSetElement* m_fieldSetAncestor;
-    mutable HTMLLegendElement* m_legendAncestor;
     OwnPtr<ValidationMessage> m_validationMessage;
-    mutable bool m_fieldSetAncestorValid : 1;
     bool m_disabled : 1;
     bool m_readOnly : 1;
     bool m_required : 1;
     bool m_valueMatchesRenderer : 1;
 
+    enum AncestorDisabledState { AncestorDisabledStateUnknown, AncestorDisabledStateEnabled, AncestorDisabledStateDisabled };
+    mutable AncestorDisabledState m_ancestorDisabledState;
     enum DataListAncestorState { Unknown, InsideDataList, NotInsideDataList };
     mutable enum DataListAncestorState m_dataListAncestorState;
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to