⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 276563 in webkit


Ignore:
Timestamp:
Apr 24, 2021, 10:59:59 PM (5 years ago)
Author:
rniwa@webkit.org
Message:

Deploy Ref/RefPtr in DeleteSelectionCommand
https://bugs.webkit.org/show_bug.cgi?id=225028

Reviewed by Wenson Hsieh.

Deployed smart pointers in DeleteSelectionCommand.

Also deployed ScriptDisallowedScope around the code which accesses the render tree.

No new tests since there should be no observable behavioral differences.

  • editing/DeleteSelectionCommand.cpp:

(WebCore::isTableRowEmpty):
(WebCore::isSpecialHTMLElement): Moved from Editing.cpp.
(WebCore::firstInSpecialElement): Ditto.
(WebCore::lastInSpecialElement): Ditto.
(WebCore::positionBeforeContainingSpecialElement): Ditto. Now returns a pair instead of returning
Position and "returning" the special element via an out argument.
(WebCore::positionAfterContainingSpecialElement): Ditto.
(WebCore::DeleteSelectionCommand::initializeStartEnd):
(WebCore::DeleteSelectionCommand::initializePositionData):
(WebCore::DeleteSelectionCommand::handleSpecialCaseBRDelete):
(WebCore::firstEditablePositionInNode):
(WebCore::DeleteSelectionCommand::insertBlockPlaceholderForTableCellIfNeeded):
(WebCore::DeleteSelectionCommand::removeNode):
(WebCore::DeleteSelectionCommand::handleGeneralDelete):
(WebCore::DeleteSelectionCommand::mergeParagraphs):
(WebCore::DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows):
(WebCore::DeleteSelectionCommand::originalStringForAutocorrectionAtBeginningOfSelection):
(WebCore::DeleteSelectionCommand::doApply):

  • editing/Editing.cpp:

(WebCore::isRenderedTable): Return false when the node is not a HTMLElement for consistency.
(WebCore::isSpecialHTMLElement): Moved to DeleteSelectionCommand.cpp.
(WebCore::firstInSpecialElement): Ditto.
(WebCore::lastInSpecialElement): Ditto.
(WebCore::positionBeforeContainingSpecialElement): Ditto.
(WebCore::positionAfterContainingSpecialElement): Ditto.

  • editing/Editing.h:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r276562 r276563  
     12021-04-24  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Deploy Ref/RefPtr in DeleteSelectionCommand
     4        https://bugs.webkit.org/show_bug.cgi?id=225028
     5
     6        Reviewed by Wenson Hsieh.
     7
     8        Deployed smart pointers in DeleteSelectionCommand.
     9
     10        Also deployed ScriptDisallowedScope around the code which accesses the render tree.
     11
     12        No new tests since there should be no observable behavioral differences.
     13
     14        * editing/DeleteSelectionCommand.cpp:
     15        (WebCore::isTableRowEmpty):
     16        (WebCore::isSpecialHTMLElement): Moved from Editing.cpp.
     17        (WebCore::firstInSpecialElement): Ditto.
     18        (WebCore::lastInSpecialElement): Ditto.
     19        (WebCore::positionBeforeContainingSpecialElement): Ditto. Now returns a pair instead of returning
     20        Position and "returning" the special element via an out argument.
     21        (WebCore::positionAfterContainingSpecialElement): Ditto.
     22        (WebCore::DeleteSelectionCommand::initializeStartEnd):
     23        (WebCore::DeleteSelectionCommand::initializePositionData):
     24        (WebCore::DeleteSelectionCommand::handleSpecialCaseBRDelete):
     25        (WebCore::firstEditablePositionInNode):
     26        (WebCore::DeleteSelectionCommand::insertBlockPlaceholderForTableCellIfNeeded):
     27        (WebCore::DeleteSelectionCommand::removeNode):
     28        (WebCore::DeleteSelectionCommand::handleGeneralDelete):
     29        (WebCore::DeleteSelectionCommand::mergeParagraphs):
     30        (WebCore::DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows):
     31        (WebCore::DeleteSelectionCommand::originalStringForAutocorrectionAtBeginningOfSelection):
     32        (WebCore::DeleteSelectionCommand::doApply):
     33        * editing/Editing.cpp:
     34        (WebCore::isRenderedTable): Return false when the node is not a HTMLElement for consistency.
     35        (WebCore::isSpecialHTMLElement): Moved to DeleteSelectionCommand.cpp.
     36        (WebCore::firstInSpecialElement): Ditto.
     37        (WebCore::lastInSpecialElement): Ditto.
     38        (WebCore::positionBeforeContainingSpecialElement): Ditto.
     39        (WebCore::positionAfterContainingSpecialElement): Ditto.
     40        * editing/Editing.h:
     41
    1422021-04-24  Tim Horton  <timothy_horton@apple.com>
    243
  • trunk/Source/WebCore/editing/DeleteSelectionCommand.cpp

    r276317 r276563  
    4444#include "RenderText.h"
    4545#include "RenderedDocumentMarker.h"
     46#include "ScriptDisallowedScope.h"
    4647#include "Text.h"
    4748#include "VisibleUnits.h"
     
    6667    if (!isTableRow(row))
    6768        return false;
    68        
    69     for (Node* child = row->firstChild(); child; child = child->nextSibling())
    70         if (isTableCell(child) && !isTableCellEmpty(child))
     69
     70    for (auto child = makeRefPtr(row->firstChild()); child; child = child->nextSibling()) {
     71        if (isTableCell(child.get()) && !isTableCellEmpty(child.get()))
    7172            return false;
    72    
     73    }
     74
    7375    return true;
     76}
     77
     78static bool isSpecialHTMLElement(const Node& node)
     79{
     80    ScriptDisallowedScope scriptDisallowedScope;
     81
     82    if (!is<HTMLElement>(node))
     83        return false;
     84
     85    if (downcast<HTMLElement>(node).isLink())
     86        return true;
     87
     88    auto* renderer = downcast<HTMLElement>(node).renderer();
     89    if (!renderer)
     90        return false;
     91
     92    if (renderer->style().display() == DisplayType::Table || renderer->style().display() == DisplayType::InlineTable)
     93        return true;
     94
     95    if (renderer->style().isFloating())
     96        return true;
     97
     98    if (renderer->style().position() != PositionType::Static)
     99        return true;
     100
     101    return false;
     102}
     103
     104static RefPtr<HTMLElement> firstInSpecialElement(const Position& position)
     105{
     106    auto rootEditableElement = makeRefPtr(position.rootEditableElement());
     107    for (auto node = makeRefPtr(position.deprecatedNode()); node && node->rootEditableElement() == rootEditableElement; node = node->parentNode()) {
     108        if (!isSpecialHTMLElement(*node))
     109            continue;
     110        VisiblePosition visiblePosition = position;
     111        VisiblePosition firstInElement = firstPositionInOrBeforeNode(node.get());
     112        if ((isRenderedTable(node.get()) && visiblePosition == firstInElement.next()) || visiblePosition == firstInElement) {
     113            RELEASE_ASSERT(is<HTMLElement>(node));
     114            return static_pointer_cast<HTMLElement>(node);
     115        }
     116    }
     117    return nullptr;
     118}
     119
     120static RefPtr<HTMLElement> lastInSpecialElement(const Position& position)
     121{
     122    auto rootEditableElement = makeRefPtr(position.rootEditableElement());
     123    for (auto node = makeRefPtr(position.deprecatedNode()); node && node->rootEditableElement() == rootEditableElement; node = node->parentNode()) {
     124        if (!isSpecialHTMLElement(*node))
     125            continue;
     126        VisiblePosition visiblePosition = position;
     127        VisiblePosition lastInElement = lastPositionInOrAfterNode(node.get());
     128        if ((isRenderedTable(node.get()) && visiblePosition == lastInElement.previous()) || visiblePosition == lastInElement) {
     129            RELEASE_ASSERT(is<HTMLElement>(node));
     130            return static_pointer_cast<HTMLElement>(node);
     131        }
     132    }
     133    return nullptr;
     134}
     135
     136static std::pair<Position, RefPtr<HTMLElement>> positionBeforeContainingSpecialElement(const Position& position)
     137{
     138    auto element = firstInSpecialElement(position);
     139    if (!element)
     140        return { position, nullptr };
     141    auto result = positionInParentBeforeNode(element.get());
     142    if (result.isNull() || result.containerNode()->rootEditableElement() != position.containerNode()->rootEditableElement())
     143        return { position, nullptr };
     144    return { result, WTFMove(element) };
     145}
     146
     147static std::pair<Position, RefPtr<HTMLElement>> positionAfterContainingSpecialElement(const Position& position)
     148{
     149    auto element = lastInSpecialElement(position);
     150    if (!element)
     151        return { position, nullptr };
     152    auto result = positionInParentAfterNode(element.get());
     153    if (result.isNull() || result.deprecatedNode()->rootEditableElement() != position.containerNode()->rootEditableElement())
     154        return { position, nullptr };
     155    return { result, WTFMove(element) };
    74156}
    75157
     
    104186
    105187void DeleteSelectionCommand::initializeStartEnd(Position& start, Position& end)
    106 {
    107     HTMLElement* startSpecialContainer = nullptr;
    108     HTMLElement* endSpecialContainer = nullptr;
    109  
     188{
    110189    start = m_selectionToDelete.start();
    111190    end = m_selectionToDelete.end();
     
    123202   
    124203    while (1) {
    125         startSpecialContainer = nullptr;
    126         endSpecialContainer = nullptr;
    127    
    128         Position s = positionBeforeContainingSpecialElement(start, &startSpecialContainer);
    129         Position e = positionAfterContainingSpecialElement(end, &endSpecialContainer);
    130        
     204        auto [startBeforeSpecialElement, startSpecialContainer] = positionBeforeContainingSpecialElement(start);
     205        auto [endAfterSpecialElement, endSpecialContainer] = positionAfterContainingSpecialElement(end);
     206
    131207        if (!startSpecialContainer && !endSpecialContainer)
    132208            break;
     
    138214
    139215        // If we're going to expand to include the startSpecialContainer, it must be fully selected.
    140         if (startSpecialContainer && !endSpecialContainer && positionInParentAfterNode(startSpecialContainer) >= end)
     216        if (startSpecialContainer && !endSpecialContainer && positionInParentAfterNode(startSpecialContainer.get()) >= end)
    141217            break;
    142218
    143219        // If we're going to expand to include the endSpecialContainer, it must be fully selected.
    144         if (endSpecialContainer && !startSpecialContainer && start >= positionInParentBeforeNode(endSpecialContainer))
     220        if (endSpecialContainer && !startSpecialContainer && start >= positionInParentBeforeNode(endSpecialContainer.get()))
    145221            break;
    146222
    147         if (startSpecialContainer && startSpecialContainer->isDescendantOf(endSpecialContainer))
     223        if (startSpecialContainer && startSpecialContainer->isDescendantOf(endSpecialContainer.get())) {
    148224            // Don't adjust the end yet, it is the end of a special element that contains the start
    149225            // special element (which may or may not be fully selected).
    150             start = s;
    151         else if (endSpecialContainer && endSpecialContainer->isDescendantOf(startSpecialContainer))
     226            start = startBeforeSpecialElement;
     227        } else if (endSpecialContainer && endSpecialContainer->isDescendantOf(startSpecialContainer.get())) {
    152228            // Don't adjust the start yet, it is the start of a special element that contains the end
    153229            // special element (which may or may not be fully selected).
    154             end = e;
    155         else {
    156             start = s;
    157             end = e;
     230            end = endAfterSpecialElement;
     231        } else {
     232            start = startBeforeSpecialElement;
     233            end = endAfterSpecialElement;
    158234        }
    159235    }
     
    246322    // If the cell is non-editable, enclosingNodeOfType won't return it by default, so
    247323    // tell that function that we don't care if it returns non-editable nodes.
    248     Node* startCell = enclosingNodeOfType(m_upstreamStart, &isTableCell, CanCrossEditingBoundary);
    249     Node* endCell = enclosingNodeOfType(m_downstreamEnd, &isTableCell, CanCrossEditingBoundary);
     324    auto startCell = makeRefPtr(enclosingNodeOfType(m_upstreamStart, &isTableCell, CanCrossEditingBoundary));
     325    auto endCell = makeRefPtr(enclosingNodeOfType(m_downstreamEnd, &isTableCell, CanCrossEditingBoundary));
    250326    // FIXME: This isn't right.  A borderless table with two rows and a single column would appear as two paragraphs.
    251327    if (endCell && endCell != startCell)
     
    359435bool DeleteSelectionCommand::handleSpecialCaseBRDelete()
    360436{
    361     Node* nodeAfterUpstreamStart = m_upstreamStart.computeNodeAfterPosition();
    362     Node* nodeAfterDownstreamStart = m_downstreamStart.computeNodeAfterPosition();
     437    auto nodeAfterUpstreamStart = makeRefPtr(m_upstreamStart.computeNodeAfterPosition());
     438    auto nodeAfterDownstreamStart = makeRefPtr(m_downstreamStart.computeNodeAfterPosition());
    363439    // Upstream end will appear before BR due to canonicalization
    364     Node* nodeAfterUpstreamEnd = m_upstreamEnd.computeNodeAfterPosition();
     440    auto nodeAfterUpstreamEnd = makeRefPtr(m_upstreamEnd.computeNodeAfterPosition());
    365441
    366442    if (!nodeAfterUpstreamStart || !nodeAfterDownstreamStart)
     
    382458    // We detect the case where the start is an empty line consisting of BR not wrapped in a block element.
    383459    if (upstreamStartIsBR && downstreamStartIsBR
    384         && !(isStartOfBlock(positionBeforeNode(nodeAfterUpstreamStart)) && isEndOfBlock(positionAfterNode(nodeAfterDownstreamStart)))
     460        && !(isStartOfBlock(positionBeforeNode(nodeAfterUpstreamStart.get())) && isEndOfBlock(positionAfterNode(nodeAfterDownstreamStart.get())))
    385461        && (!nodeAfterUpstreamEnd || nodeAfterUpstreamEnd->hasTagName(brTag) || nodeAfterUpstreamEnd->previousSibling() != nodeAfterUpstreamStart)) {
    386462        m_startsAtEmptyLine = true;
     
    394470{
    395471    ASSERT(node);
    396     Node* next = node;
     472    auto next = makeRefPtr(node);
    397473    while (next && !next->hasEditableStyle())
    398474        next = NodeTraversal::next(*next, node);
    399     return next ? firstPositionInOrBeforeNode(next) : Position();
     475    return next ? firstPositionInOrBeforeNode(next.get()) : Position();
    400476}
    401477
     
    403479{
    404480    // Make sure empty cell has some height.
    405     auto* renderer = element.renderer();
    406     if (!is<RenderTableCell>(renderer))
    407         return;
    408     if (downcast<RenderTableCell>(*renderer).contentHeight() > 0)
    409         return;
     481    {
     482        ScriptDisallowedScope scriptDisallowedScope;
     483        auto* renderer = element.renderer();
     484        if (!is<RenderTableCell>(renderer))
     485            return;
     486        if (downcast<RenderTableCell>(*renderer).contentHeight() > 0)
     487            return;
     488    }
    410489    insertBlockPlaceholder(firstEditablePositionInNode(&element));
    411490}
     
    441520                return;
    442521            // Search this non-editable region for editable regions to empty.
    443             RefPtr<Node> child = node.firstChild();
     522            auto child = makeRefPtr(node.firstChild());
    444523            while (child) {
    445                 RefPtr<Node> nextChild = child->nextSibling();
     524                auto nextChild = makeRefPtr(child->nextSibling());
    446525                removeNode(*child, shouldAssumeContentIsAlwaysEditable);
    447526                // Bail if nextChild is no longer node's child.
    448527                if (nextChild && nextChild->parentNode() != &node)
    449528                    return;
    450                 child = nextChild;
     529                child = WTFMove(nextChild);
    451530            }
    452531           
     
    459538        // Do not remove an element of table structure; remove its contents.
    460539        // Likewise for the root editable element.
    461         auto* child = NodeTraversal::next(node, &node);
     540        auto child = makeRefPtr(NodeTraversal::next(node, &node));
    462541        while (child) {
    463542            if (shouldRemoveContentOnly(*child)) {
     
    465544                continue;
    466545            }
    467             auto* remove = child;
    468             child = NodeTraversal::nextSkippingChildren(*child, &node);
    469             removeNodeUpdatingStates(*remove, shouldAssumeContentIsAlwaysEditable);
     546            auto nextChild = makeRefPtr(NodeTraversal::nextSkippingChildren(*child, &node));
     547            removeNodeUpdatingStates(*child, shouldAssumeContentIsAlwaysEditable);
     548            child = WTFMove(nextChild);
    470549        }
    471550       
     
    474553        document().updateLayoutIgnorePendingStylesheets();
    475554        // Check if we need to insert a placeholder for descendant table cells.
    476         auto* descendant = ElementTraversal::next(element, &element);
     555        auto descendant = makeRefPtr(ElementTraversal::next(element, &element));
    477556        while (descendant) {
    478             auto* placeholderCandidate = descendant;
    479             descendant = ElementTraversal::next(*descendant, &element);
    480             insertBlockPlaceholderForTableCellIfNeeded(*placeholderCandidate);
     557            auto nextDescendant = makeRefPtr(ElementTraversal::next(*descendant, &element));
     558            insertBlockPlaceholderForTableCellIfNeeded(*descendant);
     559            descendant = WTFMove(nextDescendant);
    481560        }
    482561        insertBlockPlaceholderForTableCellIfNeeded(element);
     
    536615
    537616    int startOffset = m_upstreamStart.deprecatedEditingOffset();
    538     Node* startNode = m_upstreamStart.deprecatedNode();
    539    
     617    auto startNode = makeRefPtr(m_upstreamStart.deprecatedNode());
     618
    540619    makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss();
    541620
     
    583662        bool startNodeWasDescendantOfEndNode = m_upstreamStart.deprecatedNode()->isDescendantOf(m_downstreamEnd.deprecatedNode());
    584663        // The selection to delete spans more than one node.
    585         RefPtr<Node> node(startNode);
     664        auto node = startNode.copyRef();
    586665       
    587666        if (startOffset > 0) {
    588             if (is<Text>(*startNode)) {
     667            if (is<Text>(*node)) {
    589668                // in a text node that needs to be trimmed
    590                 Text& text = downcast<Text>(*node);
     669                Text& text = downcast<Text>(*startNode);
    591670                deleteTextFromNode(text, startOffset, text.length() - startOffset);
    592                 node = NodeTraversal::next(*node);
     671                node = NodeTraversal::next(*startNode);
    593672            } else {
    594673                node = startNode->traverseToChildAt(startOffset);
    595674            }
    596675        } else if (startNode == m_upstreamEnd.deprecatedNode() && is<Text>(*startNode)) {
    597             Text& text = downcast<Text>(*m_upstreamEnd.deprecatedNode());
     676            Text& text = downcast<Text>(*startNode);
    598677            deleteTextFromNode(text, 0, m_upstreamEnd.deprecatedEditingOffset());
    599678        }
     
    612691                node = nextNode.get();
    613692            } else {
    614                 Node* n = node->lastDescendant();
    615                 if (m_downstreamEnd.deprecatedNode() == n && m_downstreamEnd.deprecatedEditingOffset() >= caretMaxOffset(*n)) {
     693                auto lastDescendant = makeRefPtr(node->lastDescendant());
     694                if (m_downstreamEnd.deprecatedNode() == lastDescendant && m_downstreamEnd.deprecatedEditingOffset() >= caretMaxOffset(*lastDescendant)) {
    616695                    removeNode(*node);
    617696                    node = nullptr;
     
    631710                    // in a text node that needs to be trimmed
    632711                    Text& text = downcast<Text>(*m_downstreamEnd.deprecatedNode());
    633                     if (m_downstreamEnd.deprecatedEditingOffset() > 0) {
     712                    if (m_downstreamEnd.deprecatedEditingOffset() > 0)
    634713                        deleteTextFromNode(text, 0, m_downstreamEnd.deprecatedEditingOffset());
    635                     }
    636714                // Remove children of m_downstreamEnd.deprecatedNode() that come after m_upstreamStart.
    637715                // Don't try to remove children if m_upstreamStart was inside m_downstreamEnd.deprecatedNode()
     
    643721                    unsigned offset = 0;
    644722                    if (m_upstreamStart.deprecatedNode()->isDescendantOf(m_downstreamEnd.deprecatedNode())) {
    645                         Node* n = m_upstreamStart.deprecatedNode();
     723                        auto n = makeRefPtr(m_upstreamStart.deprecatedNode());
    646724                        while (n && n->parentNode() != m_downstreamEnd.deprecatedNode())
    647725                            n = n->parentNode();
     
    703781    // m_downstreamEnd's block has been emptied out by deletion.  There is no content inside of it to
    704782    // move, so just remove it.
    705     Element* endBlock = enclosingBlock(m_downstreamEnd.deprecatedNode());
     783    auto endBlock = makeRefPtr(enclosingBlock(m_downstreamEnd.deprecatedNode()));
    706784    if (!endBlock)
    707785        return;
     
    730808    if (!m_startsAtEmptyLine && isStartOfParagraph(mergeDestination) && startOfParagraphToMove.absoluteCaretBounds().x() > mergeDestination.absoluteCaretBounds().x()) {
    731809        if (mergeDestination.deepEquivalent().downstream().deprecatedNode()->hasTagName(brTag)) {
    732             removeNodeAndPruneAncestors(*mergeDestination.deepEquivalent().downstream().deprecatedNode());
     810            auto nodeToRemove = makeRefPtr(mergeDestination.deepEquivalent().downstream().deprecatedNode());
     811            removeNodeAndPruneAncestors(*nodeToRemove);
    733812            m_endingPosition = startOfParagraphToMove.deepEquivalent();
    734813            return;
     
    769848{
    770849    if (m_endTableRow && m_endTableRow->isConnected() && m_endTableRow != m_startTableRow) {
    771         Node* row = m_endTableRow->previousSibling();
     850        auto row = makeRefPtr(m_endTableRow->previousSibling());
    772851        while (row && row != m_startTableRow) {
    773             RefPtr<Node> previousRow = row->previousSibling();
    774             if (isTableRowEmpty(row))
     852            auto previousRow = makeRefPtr(row->previousSibling());
     853            if (isTableRowEmpty(row.get())) {
    775854                // Use a raw removeNode, instead of DeleteSelectionCommand's, because
    776855                // that won't remove rows, it only empties them in preparation for this function.
    777856                CompositeEditCommand::removeNode(*row);
    778             row = previousRow.get();
     857            }
     858            row = WTFMove(previousRow);
    779859        }
    780860    }
     
    782862    // Remove empty rows after the start row.
    783863    if (m_startTableRow && m_startTableRow->isConnected() && m_startTableRow != m_endTableRow) {
    784         Node* row = m_startTableRow->nextSibling();
     864        auto row = makeRefPtr(m_startTableRow->nextSibling());
    785865        while (row && row != m_endTableRow) {
    786             RefPtr<Node> nextRow = row->nextSibling();
    787             if (isTableRowEmpty(row))
     866            auto nextRow = makeRefPtr(row->nextSibling());
     867            if (isTableRowEmpty(row.get()))
    788868                CompositeEditCommand::removeNode(*row);
    789             row = nextRow.get();
     869            row = WTFMove(nextRow);
    790870        }
    791871    }
     
    855935        return String();
    856936
     937    ScriptDisallowedScope scriptDisallowedScope;
    857938    for (auto* marker : document().markers().markersInRange(*rangeOfFirstCharacter, DocumentMarker::Autocorrected)) {
    858939        int startOffset = marker->startOffset();
     
    897978    // If the deletion is occurring in a text field, and we're not deleting to replace the selection, then let the frame call across the bridge to notify the form delegate.
    898979    if (!m_replace) {
    899         Element* textControl = enclosingTextFormControl(m_selectionToDelete.start());
    900         if (textControl && textControl->focused())
    901             document().editor().textWillBeDeletedInTextField(textControl);
     980        if (auto textControl = makeRefPtr(enclosingTextFormControl(m_selectionToDelete.start())); textControl && textControl->focused())
     981            document().editor().textWillBeDeletedInTextField(textControl.get());
    902982    }
    903983
     
    913993        // and ends inside it (we do need placeholders to hold open empty cells, but that's
    914994        // handled elsewhere).
    915         if (auto* table = isLastPositionBeforeTable(m_selectionToDelete.visibleStart())) {
     995        if (auto table = makeRefPtr(isLastPositionBeforeTable(m_selectionToDelete.visibleStart()))) {
    916996            if (m_selectionToDelete.end().deprecatedNode()->isDescendantOf(*table))
    917997                m_needPlaceholder = false;
     
    9621042    bool shouldRebalaceWhiteSpace = true;
    9631043    if (!document().editor().behavior().shouldRebalanceWhiteSpacesInSecureField()) {
    964         Node* node = m_endingPosition.deprecatedNode();
    965         if (is<Text>(node)) {
    966             Text& textNode = downcast<Text>(*node);
     1044        if (auto endNode = makeRefPtr(m_endingPosition.deprecatedNode()); is<Text>(endNode)) {
     1045            auto& textNode = downcast<Text>(*endNode);
     1046            ScriptDisallowedScope scriptDisallowedScope;
    9671047            if (textNode.length() && textNode.renderer())
    9681048                shouldRebalaceWhiteSpace = textNode.renderer()->style().textSecurity() == TextSecurity::None;
  • trunk/Source/WebCore/editing/Editing.cpp

    r274626 r276563  
    404404}
    405405
    406 static bool isSpecialHTMLElement(const Node* node)
    407 {
    408     if (!is<HTMLElement>(node))
    409         return false;
    410 
    411     if (downcast<HTMLElement>(*node).isLink())
    412         return true;
    413 
    414     auto* renderer = downcast<HTMLElement>(*node).renderer();
    415     if (!renderer)
    416         return false;
    417 
    418     if (renderer->style().display() == DisplayType::Table || renderer->style().display() == DisplayType::InlineTable)
    419         return true;
    420 
    421     if (renderer->style().isFloating())
    422         return true;
    423 
    424     if (renderer->style().position() != PositionType::Static)
    425         return true;
    426 
    427     return false;
    428 }
    429 
    430 static HTMLElement* firstInSpecialElement(const Position& position)
    431 {
    432     auto* rootEditableElement = position.containerNode()->rootEditableElement();
    433     for (Node* node = position.deprecatedNode(); node && node->rootEditableElement() == rootEditableElement; node = node->parentNode()) {
    434         if (!isSpecialHTMLElement(node))
    435             continue;
    436         VisiblePosition vPos(position);
    437         VisiblePosition firstInElement(firstPositionInOrBeforeNode(node));
    438         if ((isRenderedTable(node) && vPos == firstInElement.next()) || vPos == firstInElement)
    439             return &downcast<HTMLElement>(*node);
    440     }
    441     return nullptr;
    442 }
    443 
    444 static HTMLElement* lastInSpecialElement(const Position& position)
    445 {
    446     auto* rootEditableElement = position.containerNode()->rootEditableElement();
    447     for (Node* node = position.deprecatedNode(); node && node->rootEditableElement() == rootEditableElement; node = node->parentNode()) {
    448         if (!isSpecialHTMLElement(node))
    449             continue;
    450         VisiblePosition vPos(position);
    451         VisiblePosition lastInElement(lastPositionInOrAfterNode(node));
    452         if ((isRenderedTable(node) && vPos == lastInElement.previous()) || vPos == lastInElement)
    453             return &downcast<HTMLElement>(*node);
    454     }
    455     return nullptr;
    456 }
    457 
    458 Position positionBeforeContainingSpecialElement(const Position& position, HTMLElement** containingSpecialElement)
    459 {
    460     auto* element = firstInSpecialElement(position);
    461     if (!element)
    462         return position;
    463     Position result = positionInParentBeforeNode(element);
    464     if (result.isNull() || result.deprecatedNode()->rootEditableElement() != position.deprecatedNode()->rootEditableElement())
    465         return position;
    466     if (containingSpecialElement)
    467         *containingSpecialElement = element;
    468     return result;
    469 }
    470 
    471 Position positionAfterContainingSpecialElement(const Position& position, HTMLElement** containingSpecialElement)
    472 {
    473     auto* element = lastInSpecialElement(position);
    474     if (!element)
    475         return position;
    476     Position result = positionInParentAfterNode(element);
    477     if (result.isNull() || result.deprecatedNode()->rootEditableElement() != position.deprecatedNode()->rootEditableElement())
    478         return position;
    479     if (containingSpecialElement)
    480         *containingSpecialElement = element;
    481     return result;
    482 }
    483 
    484406Element* isFirstPositionAfterTable(const VisiblePosition& position)
    485407{
     
    811733bool isRenderedTable(const Node* node)
    812734{
    813     if (!is<Element>(node))
     735    if (!is<HTMLElement>(node))
    814736        return false;
    815     auto* renderer = downcast<Element>(*node).renderer();
     737    auto* renderer = downcast<HTMLElement>(*node).renderer();
    816738    return renderer && renderer->isTable();
    817739}
  • trunk/Source/WebCore/editing/Editing.h

    r266487 r276563  
    119119Position previousVisuallyDistinctCandidate(const Position&);
    120120
    121 Position positionBeforeContainingSpecialElement(const Position&, HTMLElement** containingSpecialElement = nullptr);
    122 Position positionAfterContainingSpecialElement(const Position&, HTMLElement** containingSpecialElement = nullptr);
    123 
    124121Position firstPositionInOrBeforeNode(Node*);
    125122Position lastPositionInOrAfterNode(Node*);
Note: See TracChangeset for help on using the changeset viewer.