Changeset 212140 in webkit


Ignore:
Timestamp:
Feb 10, 2017, 1:15:51 PM (9 years ago)
Author:
rniwa@webkit.org
Message:

HTMLConstructionSiteTask::Insert should never be called on a node with a parent
https://bugs.webkit.org/show_bug.cgi?id=168099

Reviewed by Sam Weinig.

insertAlreadyParsedChild always use HTMLConstructionSiteTask::InsertAlreadyParsedChild instead
of using HTMLConstructionSiteTask::Insert when fostering a child.

Also combine the step to take all children and re-parenting into a single task instead of
separately issuing TakeAllChildren and Reparent tasks.

No new tests since this is a refactoring.

  • html/parser/HTMLConstructionSite.cpp:

(WebCore::insert): Now asserts that the child node never have a parent.
(WebCore::executeInsertAlreadyParsedChildTask): Moved the code to remove the parent here.
(WebCore::executeTakeAllChildrenAndReparentTask): Renamed from executeTakeAllChildrenTask
now that this function also does the reparenting.
(WebCore::executeTask):
(WebCore::HTMLConstructionSite::reparent): Removed the variant only used with takeAllChildren.
(WebCore::HTMLConstructionSite::insertAlreadyParsedChild): Always use InsertAlreadyParsedChild
instead of calling fosterParent which uses Insert when fostering parents.
(WebCore::HTMLConstructionSite::takeAllChildrenAndReparent): Renamed from takeAllChildren.

  • html/parser/HTMLConstructionSite.h:

(WebCore::HTMLConstructionSiteTask:Operation):

  • html/parser/HTMLTreeBuilder.cpp:

(WebCore::HTMLTreeBuilder::callTheAdoptionAgency):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r212131 r212140  
     12017-02-10  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        HTMLConstructionSiteTask::Insert should never be called on a node with a parent
     4        https://bugs.webkit.org/show_bug.cgi?id=168099
     5
     6        Reviewed by Sam Weinig.
     7
     8        insertAlreadyParsedChild always use HTMLConstructionSiteTask::InsertAlreadyParsedChild instead
     9        of using HTMLConstructionSiteTask::Insert when fostering a child.
     10
     11        Also combine the step to take all children and re-parenting into a single task instead of
     12        separately issuing TakeAllChildren and Reparent tasks.
     13
     14        No new tests since this is a refactoring.
     15
     16        * html/parser/HTMLConstructionSite.cpp:
     17        (WebCore::insert): Now asserts that the child node never have a parent.
     18        (WebCore::executeInsertAlreadyParsedChildTask): Moved the code to remove the parent here.
     19        (WebCore::executeTakeAllChildrenAndReparentTask): Renamed from executeTakeAllChildrenTask
     20        now that this function also does the reparenting.
     21        (WebCore::executeTask):
     22        (WebCore::HTMLConstructionSite::reparent): Removed the variant only used with takeAllChildren.
     23        (WebCore::HTMLConstructionSite::insertAlreadyParsedChild): Always use InsertAlreadyParsedChild
     24        instead of calling fosterParent which uses Insert when fostering parents.
     25        (WebCore::HTMLConstructionSite::takeAllChildrenAndReparent): Renamed from takeAllChildren.
     26        * html/parser/HTMLConstructionSite.h:
     27        (WebCore::HTMLConstructionSiteTask:Operation):
     28        * html/parser/HTMLTreeBuilder.cpp:
     29        (WebCore::HTMLTreeBuilder::callTheAdoptionAgency):
     30
    1312017-02-10  Dave Hyatt  <hyatt@apple.com>
    232
  • trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp

    r210319 r212140  
    106106        task.parent = &downcast<HTMLTemplateElement>(*task.parent).content();
    107107
    108     if (ContainerNode* parent = task.child->parentNode())
    109         parent->parserRemoveChild(*task.child);
    110 
     108    ASSERT(!task.child->parentNode());
    111109    if (task.nextChild)
    112110        task.parent->parserInsertBefore(*task.child, *task.nextChild);
     
    141139    ASSERT(task.operation == HTMLConstructionSiteTask::InsertAlreadyParsedChild);
    142140
     141    if (ContainerNode* parent = task.child->parentNode())
     142        parent->parserRemoveChild(*task.child);
    143143    insert(task);
    144144}
    145145
    146 static inline void executeTakeAllChildrenTask(HTMLConstructionSiteTask& task)
    147 {
    148     ASSERT(task.operation == HTMLConstructionSiteTask::TakeAllChildren);
    149 
    150     task.parent->takeAllChildrenFrom(task.oldParent());
    151     // Notice that we don't need to manually attach the moved children
    152     // because takeAllChildrenFrom does that work for us.
     146static inline void executeTakeAllChildrenAndReparentTask(HTMLConstructionSiteTask& task)
     147{
     148    ASSERT(task.operation == HTMLConstructionSiteTask::TakeAllChildrenAndReparent);
     149
     150    auto* furthestBlock = task.oldParent();
     151    task.parent->takeAllChildrenFrom(furthestBlock);
     152
     153    furthestBlock->parserAppendChild(*task.parent);
    153154}
    154155
     
    166167        executeReparentTask(task);
    167168        return;
    168     case HTMLConstructionSiteTask::TakeAllChildren:
    169         executeTakeAllChildrenTask(task);
     169    case HTMLConstructionSiteTask::TakeAllChildrenAndReparent:
     170        executeTakeAllChildrenAndReparentTask(task);
    170171        return;
    171172    }
     
    600601}
    601602
    602 void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord& newParent, HTMLStackItem& child)
    603 {
    604     HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Reparent);
    605     task.parent = &newParent.node();
     603void HTMLConstructionSite::insertAlreadyParsedChild(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& child)
     604{
     605    HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertAlreadyParsedChild);
     606    if (causesFosterParenting(newParent)) {
     607        findFosterSite(task);
     608        ASSERT(task.parent);
     609    } else
     610        task.parent = &newParent.node();
    606611    task.child = &child.element();
    607612    m_taskQueue.append(WTFMove(task));
    608613}
    609614
    610 void HTMLConstructionSite::insertAlreadyParsedChild(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& child)
    611 {
    612     if (causesFosterParenting(newParent)) {
    613         fosterParent(child.element());
    614         return;
    615     }
    616 
    617     HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertAlreadyParsedChild);
    618     task.parent = &newParent.node();
    619     task.child = &child.element();
    620     m_taskQueue.append(WTFMove(task));
    621 }
    622 
    623 void HTMLConstructionSite::takeAllChildren(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& oldParent)
    624 {
    625     HTMLConstructionSiteTask task(HTMLConstructionSiteTask::TakeAllChildren);
     615void HTMLConstructionSite::takeAllChildrenAndReparent(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& oldParent)
     616{
     617    HTMLConstructionSiteTask task(HTMLConstructionSiteTask::TakeAllChildrenAndReparent);
    626618    task.parent = &newParent.node();
    627619    task.child = &oldParent.node();
  • trunk/Source/WebCore/html/parser/HTMLConstructionSite.h

    r208985 r212140  
    4242        InsertAlreadyParsedChild,
    4343        Reparent,
    44         TakeAllChildren,
     44        TakeAllChildrenAndReparent,
    4545    };
    4646
     
    120120
    121121    void reparent(HTMLElementStack::ElementRecord& newParent, HTMLElementStack::ElementRecord& child);
    122     void reparent(HTMLElementStack::ElementRecord& newParent, HTMLStackItem& child);
    123122    // insertAlreadyParsedChild assumes that |child| has already been parsed (i.e., we're just
    124123    // moving it around in the tree rather than parsing it for the first time). That means
    125124    // this function doesn't call beginParsingChildren / finishParsingChildren.
    126125    void insertAlreadyParsedChild(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& child);
    127     void takeAllChildren(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& oldParent);
     126    void takeAllChildrenAndReparent(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& oldParent);
    128127
    129128    Ref<HTMLStackItem> createElementFromSavedToken(HTMLStackItem&);
  • trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp

    r211645 r212140  
    14971497        // 11.
    14981498        auto newItem = m_tree.createElementFromSavedToken(formattingElementRecord->stackItem());
    1499         // 12.
    1500         m_tree.takeAllChildren(newItem, *furthestBlock);
    1501         // 13.
    1502         m_tree.reparent(*furthestBlock, newItem);
     1499        // 12. & 13.
     1500        m_tree.takeAllChildrenAndReparent(newItem, *furthestBlock);
    15031501        // 14.
    15041502        m_tree.activeFormattingElements().swapTo(*formattingElement, newItem.copyRef(), bookmark);
Note: See TracChangeset for help on using the changeset viewer.