Changeset 143834 in webkit


Ignore:
Timestamp:
Feb 22, 2013 8:47:20 PM (11 years ago)
Author:
akling@apple.com
Message:

Attr: Simplify modification callbacks.
<http://webkit.org/b/110598>

Reviewed by Antti Koivisto.

Instead of Attr being a friend of Element and grabbing at various internal storage and callbacks,
let Attr simply call Element::setAttribute() when its value is changed, and do all that business
from Element.

  • dom/Element.h:
  • dom/Element.cpp:

(WebCore::Element::setAttributeInternal):

Call Attr::recreateTextChildAfterAttributeValueChanged() after modifying an attribute value instead
of doing the modification through the Attr node.

  • dom/Attr.h:
  • dom/Attr.cpp:

(WebCore::Attr::Attr):
(WebCore::Attr::childrenChanged):

Added an m_inChildrenChanged flag so we can prevent infinite callback recursion in childrenChanged().

(WebCore::Attr::setValue):

Call Element::setAttribute() instead of modifying the attribute storage directly.

(WebCore::Attr::recreateTextChildAfterAttributeValueChanged):

Factored out the "remove all children / create a new text child with attribute value" logic into
a separate function.

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r143832 r143834  
     12013-02-22  Andreas Kling  <akling@apple.com>
     2
     3        Attr: Simplify modification callbacks.
     4        <http://webkit.org/b/110598>
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Instead of Attr being a friend of Element and grabbing at various internal storage and callbacks,
     9        let Attr simply call Element::setAttribute() when its value is changed, and do all that business
     10        from Element.
     11
     12        * dom/Element.h:
     13        * dom/Element.cpp:
     14        (WebCore::Element::setAttributeInternal):
     15
     16            Call Attr::recreateTextChildAfterAttributeValueChanged() after modifying an attribute value instead
     17            of doing the modification through the Attr node.
     18
     19        * dom/Attr.h:
     20        * dom/Attr.cpp:
     21        (WebCore::Attr::Attr):
     22        (WebCore::Attr::childrenChanged):
     23
     24            Added an m_inChildrenChanged flag so we can prevent infinite callback recursion in childrenChanged().
     25
     26        (WebCore::Attr::setValue):
     27
     28            Call Element::setAttribute() instead of modifying the attribute storage directly.
     29
     30        (WebCore::Attr::recreateTextChildAfterAttributeValueChanged):
     31
     32            Factored out the "remove all children / create a new text child with attribute value" logic into
     33            a separate function.
     34
    1352013-02-22  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
    236
  • trunk/Source/WebCore/dom/Attr.cpp

    r142827 r143834  
    44 *           (C) 2001 Peter Kelly (pmk@post.com)
    55 *           (C) 2001 Dirk Mueller (mueller@kde.org)
    6  * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2012 Apple Inc. All rights reserved.
     6 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
    77 *
    88 * This library is free software; you can redistribute it and/or
     
    3030#include "Text.h"
    3131#include "XMLNSNames.h"
     32#include <wtf/TemporaryChange.h>
    3233#include <wtf/text/AtomicString.h>
    3334#include <wtf/text/StringBuilder.h>
     
    4243    , m_name(name)
    4344    , m_ignoreChildrenChanged(0)
     45    , m_inChildrenChanged(false)
    4446    , m_specified(true)
    4547{
     
    5254    , m_standaloneValue(standaloneValue)
    5355    , m_ignoreChildrenChanged(0)
     56    , m_inChildrenChanged(false)
    5457    , m_specified(true)
    5558{
     
    108111}
    109112
    110 void Attr::setValue(const AtomicString& value)
    111 {
     113void Attr::recreateTextChildAfterAttributeValueChanged()
     114{
     115    if (m_inChildrenChanged)
     116        return;
    112117    EventQueueScope scope;
    113118    m_ignoreChildrenChanged++;
    114119    removeChildren();
    115     if (m_element)
    116         elementAttribute().setValue(value);
    117     else
    118         m_standaloneValue = value;
    119120    createTextChild();
    120121    m_ignoreChildrenChanged--;
    121 
     122}
     123
     124void Attr::setValue(const AtomicString& value)
     125{
    122126    invalidateNodeListCachesInAncestors(&m_name, m_element);
     127
     128    if (m_element) {
     129        m_element->setAttribute(m_name, value);
     130        return;
     131    }
     132    m_standaloneValue = value;
     133    recreateTextChildAfterAttributeValueChanged();
    123134}
    124135
    125136void Attr::setValue(const AtomicString& value, ExceptionCode&)
    126137{
    127     if (m_element)
    128         m_element->willModifyAttribute(qualifiedName(), this->value(), value);
    129 
    130138    setValue(value);
    131 
    132     if (m_element)
    133         m_element->didModifyAttribute(qualifiedName(), value);
    134139}
    135140
     
    163168        return;
    164169
    165     invalidateNodeListCachesInAncestors(&qualifiedName(), m_element);
     170    TemporaryChange<bool> changeInChildrenChanged(m_inChildrenChanged, true);
    166171
    167172    // FIXME: We should include entity references in the value
     
    173178    }
    174179
    175     AtomicString newValue = valueBuilder.toAtomicString();
    176     if (m_element)
    177         m_element->willModifyAttribute(qualifiedName(), value(), newValue);
    178 
    179     if (m_element)
    180         elementAttribute().setValue(newValue);
    181     else
    182         m_standaloneValue = newValue;
    183 
    184     if (m_element)
    185         m_element->attributeChanged(qualifiedName(), newValue);
     180    setValue(valueBuilder.toAtomicString());
    186181}
    187182
  • trunk/Source/WebCore/dom/Attr.h

    r127228 r143834  
    6565    void detachFromElementWithValue(const AtomicString&);
    6666
     67    void recreateTextChildAfterAttributeValueChanged();
     68
    6769private:
    6870    Attr(Element*, const QualifiedName&);
     
    102104
    103105    RefPtr<StylePropertySet> m_style;
    104     unsigned m_ignoreChildrenChanged : 31;
    105     bool m_specified : 1;
     106    unsigned short m_ignoreChildrenChanged;
     107    bool m_inChildrenChanged;
     108    bool m_specified;
    106109};
    107110
  • trunk/Source/WebCore/dom/Element.cpp

    r143743 r143834  
    809809
    810810    if (newValue != attributeItem(index)->value()) {
    811         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
    812         // will write into the ElementData.
    813         // FIXME: Refactor this so it makes some sense.
     811        ensureUniqueElementData()->attributeItem(index)->setValue(newValue);
     812
    814813        if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(name))
    815             attrNode->setValue(newValue);
    816         else
    817             ensureUniqueElementData()->attributeItem(index)->setValue(newValue);
     814            attrNode->recreateTextChildAfterAttributeValueChanged();
    818815    }
    819816
  • trunk/Source/WebCore/dom/Element.h

    r143743 r143834  
    638638    virtual bool alwaysCreateUserAgentShadowRoot() const { return false; }
    639639
    640     // FIXME: Remove the need for Attr to call willModifyAttribute/didModifyAttribute.
    641     friend class Attr;
    642 
    643640    enum SynchronizationOfLazyAttribute { NotInSynchronizationOfLazyAttribute = 0, InSynchronizationOfLazyAttribute };
    644641
Note: See TracChangeset for help on using the changeset viewer.