Changeset 106465 in webkit


Ignore:
Timestamp:
Feb 1, 2012 5:50:25 AM (12 years ago)
Author:
commit-queue@webkit.org
Message:

Content element should be able to be dynamically added/removed/replaced in a shadow tree.
https://bugs.webkit.org/show_bug.cgi?id=76611

Patch by Shinya Kawanaka <shinyak@google.com> on 2012-02-01
Reviewed by Hajime Morita

Source/WebCore:

When a content element is added/removed/replaced in a shadow tree, we have to recreate
the shadow tree to recalculate inclusions of content elements. Currently we didn't recalculate it
when content element is removed. (When added, it is recalculated.)
This patch enables us to recalcurate the shadow tree when content element is removed.

Test: fast/dom/shadow/content-element-move.html

  • dom/Element.cpp:

(WebCore::Element::attach):

If a shadow root exists, attaches shadow tree before attaching child elements.

  • dom/ShadowRoot.cpp: Added a flag to recalculate shadow tree.

(WebCore::ShadowRoot::ShadowRoot):
(WebCore::ShadowRoot::recalcShadowTreeStyle):

Recalculates light children and shadow tree.

(WebCore::ShadowRoot::setNeedsReattachHostChildrenAndShadow):
(WebCore::ShadowRoot::reattachHostChildrenAndShadow):

Detaches shadow tree and host light children, and attaches them again.

  • dom/ShadowRoot.h:

(WebCore::ShadowRoot::clearNeedsReattachHostChildrenAndShadow):
(WebCore::ShadowRoot::needsReattachHostChildrenAndShadow):

  • html/shadow/HTMLContentElement.cpp:

(WebCore::HTMLContentElement::attach):

Does not need to detach included elements, because they are not attached in ContainerNode anymore.

(WebCore::HTMLContentElement::detach):

When a content element detached, reattaches a shadow tree.

LayoutTests:

Test cases for appending/removing/replacing content element in a shadow tree.

  • fast/dom/shadow/content-element-move-expected.txt: Added.
  • fast/dom/shadow/content-element-move.html: Added.
Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r106464 r106465  
     12012-02-01  Shinya Kawanaka  <shinyak@google.com>
     2
     3        Content element should be able to be dynamically added/removed/replaced in a shadow tree.
     4        https://bugs.webkit.org/show_bug.cgi?id=76611
     5
     6        Reviewed by Hajime Morita
     7
     8        Test cases for appending/removing/replacing content element in a shadow tree.
     9
     10        * fast/dom/shadow/content-element-move-expected.txt: Added.
     11        * fast/dom/shadow/content-element-move.html: Added.
     12
    1132012-02-01  Peter Beverloo  <peter@chromium.org>
    214
  • trunk/Source/WebCore/ChangeLog

    r106464 r106465  
     12012-02-01  Shinya Kawanaka  <shinyak@google.com>
     2
     3        Content element should be able to be dynamically added/removed/replaced in a shadow tree.
     4        https://bugs.webkit.org/show_bug.cgi?id=76611
     5
     6        Reviewed by Hajime Morita
     7
     8        When a content element is added/removed/replaced in a shadow tree, we have to recreate
     9        the shadow tree to recalculate inclusions of content elements. Currently we didn't recalculate it
     10        when content element is removed. (When added, it is recalculated.)
     11        This patch enables us to recalcurate the shadow tree when content element is removed.
     12
     13        Test: fast/dom/shadow/content-element-move.html
     14
     15        * dom/Element.cpp:
     16        (WebCore::Element::attach):
     17          If a shadow root exists, attaches shadow tree before attaching child elements.
     18        * dom/ShadowRoot.cpp:
     19          Added a flag to recalculate shadow tree.
     20        (WebCore::ShadowRoot::ShadowRoot):
     21        (WebCore::ShadowRoot::recalcShadowTreeStyle):
     22          Recalculates light children and shadow tree.
     23        (WebCore::ShadowRoot::setNeedsReattachHostChildrenAndShadow):
     24        (WebCore::ShadowRoot::reattachHostChildrenAndShadow):
     25          Detaches shadow tree and host light children, and attaches them again.
     26        * dom/ShadowRoot.h:
     27        (WebCore::ShadowRoot::clearNeedsReattachHostChildrenAndShadow):
     28        (WebCore::ShadowRoot::needsReattachHostChildrenAndShadow):
     29        * html/shadow/HTMLContentElement.cpp:
     30        (WebCore::HTMLContentElement::attach):
     31          Does not need to detach included elements, because they are not attached in ContainerNode anymore.
     32        (WebCore::HTMLContentElement::detach):
     33          When a content element detached, reattaches a shadow tree.
     34
    1352012-02-01  Peter Beverloo  <peter@chromium.org>
    236
  • trunk/Source/WebCore/dom/Element.cpp

    r106451 r106465  
    941941
    942942    createRendererIfNeeded();
    943    
    944943    StyleSelectorParentPusher parentPusher(this);
    945944
    946     if (firstChild())
    947         parentPusher.push();
    948     ContainerNode::attach();
    949 
     945    // When a shadow root exists, it does the work of attaching the children.
    950946    if (ShadowRoot* shadow = shadowRoot()) {
    951947        parentPusher.push();
     948        Node::attach();
    952949        shadow->attach();
     950
     951        // In a shadow tree, some of light children may be attached by 'content' element.
     952        // However, when there is no content element or content element does not select
     953        // all light children, we have to attach the rest of light children here.
     954        for (Node* child = firstChild(); child; child = child->nextSibling()) {
     955            if (!child->attached())
     956                child->attach();
     957        }
     958    } else {
     959        if (firstChild())
     960            parentPusher.push();
     961        ContainerNode::attach();
    953962    }
    954963
  • trunk/Source/WebCore/dom/ShadowRoot.cpp

    r106451 r106465  
    4040    : TreeScope(document, CreateShadowRoot)
    4141    , m_applyAuthorSheets(false)
     42    , m_needsRecalculateContent(false)
    4243{
    4344    ASSERT(document);
     
    100101void ShadowRoot::recalcShadowTreeStyle(StyleChange change)
    101102{
    102     if (hasContentElement())
    103         reattach();
     103    if (needsReattachHostChildrenAndShadow())
     104        reattachHostChildrenAndShadow();
    104105    else {
    105106        for (Node* n = firstChild(); n; n = n->nextSibling()) {
     
    111112    }
    112113
     114    clearNeedsReattachHostChildrenAndShadow();
    113115    clearNeedsStyleRecalc();
    114116    clearChildNeedsStyleRecalc();
     117}
     118
     119void ShadowRoot::setNeedsReattachHostChildrenAndShadow()
     120{
     121    m_needsRecalculateContent = true;
     122    if (shadowHost())
     123        shadowHost()->setNeedsStyleRecalc();
    115124}
    116125
     
    169178}
    170179
     180void ShadowRoot::reattachHostChildrenAndShadow()
     181{
     182    Node* hostNode = host();
     183    if (!hostNode)
     184        return;
     185
     186    for (Node* child = hostNode->firstChild(); child; child = child->nextSibling()) {
     187        if (child->attached())
     188            child->detach();
     189    }
     190
     191    reattach();
     192
     193    for (Node* child = hostNode->firstChild(); child; child = child->nextSibling()) {
     194        if (!child->attached())
     195            child->attach();
     196    }
     197}
     198
    171199ContentInclusionSelector* ShadowRoot::inclusions() const
    172200{
  • trunk/Source/WebCore/dom/ShadowRoot.h

    r106451 r106465  
    4444    void recalcShadowTreeStyle(StyleChange);
    4545
     46    void setNeedsReattachHostChildrenAndShadow();
     47    void clearNeedsReattachHostChildrenAndShadow();
     48    bool needsReattachHostChildrenAndShadow();
     49
    4650    HTMLContentElement* includerFor(Node*) const;
    4751    void hostChildrenChanged();
     
    4953
    5054    virtual void attach();
     55    void reattachHostChildrenAndShadow();
    5156
    5257    virtual bool applyAuthorSheets() const;
     
    6974    bool hasContentElement() const;
    7075
    71     bool m_applyAuthorSheets;
     76    bool m_applyAuthorSheets : 1;
     77    bool m_needsRecalculateContent : 1;
    7278    OwnPtr<ContentInclusionSelector> m_inclusions;
    7379};
     
    7682{
    7783    return adoptRef(new ShadowRoot(document));
     84}
     85
     86inline void ShadowRoot::clearNeedsReattachHostChildrenAndShadow()
     87{
     88    m_needsRecalculateContent = false;
     89}
     90
     91inline bool ShadowRoot::needsReattachHostChildrenAndShadow()
     92{
     93    return m_needsRecalculateContent || hasContentElement();
    7894}
    7995
  • trunk/Source/WebCore/html/shadow/HTMLContentElement.cpp

    r106451 r106465  
    8484    if (root) {
    8585        for (ShadowInclusion* inclusion = m_inclusions->first(); inclusion; inclusion = inclusion->next())
    86             inclusion->content()->detach();
    87         for (ShadowInclusion* inclusion = m_inclusions->first(); inclusion; inclusion = inclusion->next())
    8886            inclusion->content()->attach();
    8987    }
     
    9593        if (ContentInclusionSelector* selector = root->inclusions())
    9694            selector->unselect(m_inclusions.get());
     95
     96        // When content element is detached, shadow tree should be recreated to re-calculate inclusions for
     97        // other content elements.
     98        root->setNeedsReattachHostChildrenAndShadow();
    9799    }
    98100
Note: See TracChangeset for help on using the changeset viewer.