Changeset 276131 in webkit
- Timestamp:
- Apr 16, 2021, 3:21:45 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 edited
-
ChangeLog (modified) (1 diff)
-
editing/CompositeEditCommand.cpp (modified) (27 diffs)
-
editing/CompositeEditCommand.h (modified) (4 diffs)
-
editing/EditCommand.cpp (modified) (5 diffs)
-
editing/EditCommand.h (modified) (3 diffs)
-
editing/InsertTextCommand.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r276124 r276131 1 2021-04-16 Ryosuke Niwa <rniwa@webkit.org> 2 3 Deploy Ref/RefPtr/WeakPtr in EditCommand and CompositeEditCommand 4 https://bugs.webkit.org/show_bug.cgi?id=224659 5 6 Reviewed by Antti Koivisto. 7 8 Deployed Ref/RefPtr/WeakPtr across CompositeEditCommand and EditCommand. 9 10 Also wrapped sections of code that access render tree with ScriptDisallowedScope. 11 12 * editing/CompositeEditCommand.cpp: 13 (WebCore::postTextStateChangeNotification): 14 (WebCore::CompositeEditCommand::ensureComposition): 15 (WebCore::CompositeEditCommand::isRemovableBlock): Let a raw pointer to the parent node here 16 since the only thing we do is to call hasOneChild on it. 17 (WebCore::CompositeEditCommand::insertNodeBefore): 18 (WebCore::CompositeEditCommand::insertNodeAfter): 19 (WebCore::CompositeEditCommand::insertNodeAt): 20 (WebCore::CompositeEditCommand::removeChildrenInRange): 21 (WebCore::CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAttributes): 22 (WebCore::CompositeEditCommand::positionOutsideTabSpan): 23 (WebCore::CompositeEditCommand::textNodeForRebalance const): Renamed from canRebalance and 24 now returns the text node after downcasting so that rebalanceWhitespaceAt doesn't need to have 25 a lone downcast without a type check. 26 (WebCore::CompositeEditCommand::rebalanceWhitespaceAt): 27 (WebCore::CompositeEditCommand::rebalanceWhitespaceOnTextSubstring): 28 (WebCore::CompositeEditCommand::prepareWhitespaceAtPositionForSplit): 29 (WebCore::CompositeEditCommand::deleteInsignificantText): 30 (WebCore::CompositeEditCommand::addBlockPlaceholderIfNeeded): 31 (WebCore::CompositeEditCommand::cloneParagraphUnderNewElement): 32 (WebCore::CompositeEditCommand::moveParagraphs): 33 * editing/CompositeEditCommand.h: 34 (WebCore::CompositeEditCommand): Now inherits from CanMakeWeakPtr. 35 (WebCore::toCompositeEditCommand): Deleted. 36 * editing/EditCommand.cpp: 37 (WebCore::EditCommand::EditCommand): Initialize m_startingSelection and m_endingSelection directly 38 since setStartingSelection and setEndingSelection now stores "this" pointer in RefPtr. 39 There is no behavior difference since m_parent and CompositeEditCommand::m_composition if applicable 40 are both nullptr at this point. 41 (WebCore::compositionIfPossible): 42 (WebCore::EditCommand::isEditingTextAreaOrTextInput const): Use enclosingTextFormControl instead 43 of duplicating the code here. 44 (WebCore::EditCommand::setStartingSelection): 45 (WebCore::EditCommand::setEndingSelection): 46 (WebCore::EditCommand::setParent): 47 (WebCore::EditCommand::postTextStateChangeNotification): 48 * editing/EditCommand.h: 49 (WebCore::EditCommand::parent const): 50 * editing/InsertTextCommand.cpp: 51 (WebCore::InsertTextCommand::doApply): 52 1 53 2021-04-16 Youenn Fablet <youenn@apple.com> 2 54 -
trunk/Source/WebCore/editing/CompositeEditCommand.cpp
r275657 r276131 65 65 #include "ReplaceSelectionCommand.h" 66 66 #include "ScopedEventQueue.h" 67 #include "ScriptDisallowedScope.h" 67 68 #include "SetNodeAttributeCommand.h" 68 69 #include "SplitElementCommand.h" … … 152 153 { 153 154 ASSERT(cache); 154 auto * node = highestEditableRoot(position.deepEquivalent(), HasEditableAXRole);155 auto node = makeRefPtr(highestEditableRoot(position.deepEquivalent(), HasEditableAXRole)); 155 156 if (!node) 156 157 return; 157 158 if (insertedText.length() && deletedText.length()) 158 cache->postTextReplacementNotification(node , AXTextEditTypeDelete, insertedText, AXTextEditTypeInsert, deletedText, position);159 cache->postTextReplacementNotification(node.get(), AXTextEditTypeDelete, insertedText, AXTextEditTypeInsert, deletedText, position); 159 160 else if (deletedText.length()) 160 cache->postTextStateChangeNotification(node , AXTextEditTypeInsert, deletedText, position);161 cache->postTextStateChangeNotification(node.get(), AXTextEditTypeInsert, deletedText, position); 161 162 else if (insertedText.length()) 162 cache->postTextStateChangeNotification(node , AXTextEditTypeDelete, insertedText, position);163 cache->postTextStateChangeNotification(node.get(), AXTextEditTypeDelete, insertedText, position); 163 164 } 164 165 … … 442 443 EditCommandComposition& CompositeEditCommand::ensureComposition() 443 444 { 444 auto * command = this;445 auto command = makeRefPtr(this); 445 446 while (auto* parent = command->parent()) 446 447 command = parent; … … 537 538 { 538 539 ASSERT(node); 540 // FIXME: We should support other elements that can be removed. 539 541 if (!is<HTMLDivElement>(*node)) 540 542 return false; 541 543 542 Node* parentNode = node->parentNode();543 if ( parentNode && parentNode->firstChild() != parentNode->lastChild())544 auto* parentNode = node->parentNode(); 545 if (!parentNode || !parentNode->hasOneChild()) 544 546 return false; 545 547 … … 552 554 void CompositeEditCommand::insertNodeBefore(Ref<Node>&& insertChild, Node& refChild, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable) 553 555 { 554 auto * parent = refChild.parentNode();556 auto parent = makeRefPtr(refChild.parentNode()); 555 557 if (!parent || (!parent->hasEditableStyle() && parent->renderer())) 556 558 return; … … 560 562 void CompositeEditCommand::insertNodeAfter(Ref<Node>&& insertChild, Node& refChild) 561 563 { 562 ContainerNode* parent = refChild.parentNode();564 auto parent = makeRefPtr(refChild.parentNode()); 563 565 if (!parent) 564 566 return; … … 579 581 // likewise for replaced elements, brs, etc. 580 582 Position p = editingPosition.parentAnchoredEquivalent(); 581 Node* refChild = p.deprecatedNode();583 auto refChild = makeRefPtr(p.deprecatedNode()); 582 584 int offset = p.deprecatedEditingOffset(); 583 585 584 586 if (canHaveChildrenForEditing(*refChild)) { 585 Node* child = refChild->firstChild();587 auto child = makeRefPtr(refChild->firstChild()); 586 588 for (int i = 0; child && i < offset; i++) 587 589 child = child->nextSibling(); … … 612 614 { 613 615 Vector<Ref<Node>> children; 614 Node* child = node.traverseToChildAt(from);616 auto child = makeRefPtr(node.traverseToChildAt(from)); 615 617 for (unsigned i = from; child && i < to; i++, child = child->nextSibling()) 616 618 children.append(*child); … … 667 669 // reduce the number of edit commands could do so here. 668 670 auto command = ReplaceNodeWithSpanCommand::create(element); 669 auto* commandPtr = command.ptr(); 670 applyCommandToComposite(WTFMove(command)); 671 applyCommandToComposite(command); 671 672 // Returning a raw pointer here is OK because the command is retained by 672 673 // applyCommandToComposite (thus retaining the span), and the span is also 673 674 // in the DOM tree, and thus alive whie it has a parent. 674 ASSERT(command Ptr->spanElement()->isConnected());675 return command Ptr->spanElement();675 ASSERT(command->spanElement()->isConnected()); 676 return command->spanElement(); 676 677 } 677 678 … … 823 824 } 824 825 825 auto * tabSpan = tabSpanNode(position.containerNode());826 auto tabSpan = makeRefPtr(tabSpanNode(position.containerNode())); 826 827 827 828 if (position.offsetInContainerNode() <= caretMinOffset(*position.containerNode())) 828 return positionInParentBeforeNode(tabSpan );829 return positionInParentBeforeNode(tabSpan.get()); 829 830 830 831 if (position.offsetInContainerNode() >= caretMaxOffset(*position.containerNode())) 831 return positionInParentAfterNode(tabSpan );832 return positionInParentAfterNode(tabSpan.get()); 832 833 833 834 splitTextNodeContainingElement(downcast<Text>(*position.containerNode()), position.offsetInContainerNode()); 834 return positionInParentBeforeNode(tabSpan );835 return positionInParentBeforeNode(tabSpan.get()); 835 836 } 836 837 … … 887 888 } 888 889 889 bool CompositeEditCommand::canRebalance(const Position& position) const890 { 891 Node* node = position.containerNode();890 RefPtr<Text> CompositeEditCommand::textNodeForRebalance(const Position& position) const 891 { 892 auto node = makeRefPtr(position.containerNode()); 892 893 if (position.anchorType() != Position::PositionIsOffsetInAnchor || !is<Text>(node)) 893 return false; 894 895 Text& textNode = downcast<Text>(*node); 896 if (!textNode.length()) 897 return false; 898 899 node->document().updateStyleIfNeeded(); 900 901 RenderObject* renderer = textNode.renderer(); 894 return nullptr; 895 896 auto textNode = static_pointer_cast<Text>(std::exchange(node, nullptr)); 897 if (!textNode->length()) 898 return nullptr; 899 900 textNode->document().updateStyleIfNeeded(); 901 902 ScriptDisallowedScope::InMainThread scriptDisallowedScope; 903 904 RenderObject* renderer = textNode->renderer(); 902 905 if (renderer && !renderer->style().collapseWhiteSpace()) 903 return false;904 905 return t rue;906 return nullptr; 907 908 return textNode; 906 909 } 907 910 … … 909 912 void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position) 910 913 { 911 Node* node = position.containerNode();912 if (! canRebalance(position))914 auto textNode = textNodeForRebalance(position); 915 if (!textNode) 913 916 return; 914 917 915 918 // If the rebalance is for the single offset, and neither text[offset] nor text[offset - 1] are some form of whitespace, do nothing. 916 919 int offset = position.deprecatedEditingOffset(); 917 String text = downcast<Text>(*node).data();920 String text = textNode->data(); 918 921 if (!deprecatedIsEditingWhitespace(text[offset])) { 919 922 offset--; … … 922 925 } 923 926 924 rebalanceWhitespaceOnTextSubstring( downcast<Text>(*node), position.offsetInContainerNode(), position.offsetInContainerNode());927 rebalanceWhitespaceOnTextSubstring(*textNode, position.offsetInContainerNode(), position.offsetInContainerNode()); 925 928 } 926 929 … … 931 934 932 935 // Set upstream and downstream to define the extent of the whitespace surrounding text[offset]. 933 int upstream = startOffset;936 unsigned upstream = std::max(0, startOffset); 934 937 while (upstream > 0 && deprecatedIsEditingWhitespace(text[upstream - 1])) 935 938 upstream--; 936 939 937 int downstream = endOffset;938 while ( (unsigned)downstream < text.length() && deprecatedIsEditingWhitespace(text[downstream]))940 unsigned downstream = std::max(0, endOffset); 941 while (downstream < text.length() && deprecatedIsEditingWhitespace(text[downstream])) 939 942 downstream++; 940 943 … … 947 950 948 951 String string = text.substring(upstream, length); 949 String rebalancedString = stringWithRebalancedWhitespace(string,950 952 // FIXME: Because of the problem mentioned at the top of this function, we must also use nbsps at the start/end of the string because 951 953 // this function doesn't get all surrounding whitespace, just the whitespace in the current text node. 952 isStartOfParagraph(visibleUpstreamPos) || upstream == 0,953 isEndOfParagraph(visibleDownstreamPos) || (unsigned)downstream == text.length());954 954 String rebalancedString = stringWithRebalancedWhitespace(string, isStartOfParagraph(visibleUpstreamPos) || !upstream, 955 isEndOfParagraph(visibleDownstreamPos) || downstream == text.length()); 956 955 957 if (string != rebalancedString) 956 958 replaceTextInNodePreservingMarkers(textNode, upstream, length, rebalancedString); … … 959 961 void CompositeEditCommand::prepareWhitespaceAtPositionForSplit(Position& position) 960 962 { 961 Node* node = position.deprecatedNode();963 auto node = makeRefPtr(position.deprecatedNode()); 962 964 if (!is<Text>(node)) 963 965 return; … … 966 968 if (!textNode.length()) 967 969 return; 968 RenderObject* renderer = textNode.renderer(); 969 if (renderer && !renderer->style().collapseWhiteSpace()) 970 return; 970 971 { 972 ScriptDisallowedScope::InMainThread scriptDisallowedScope; 973 RenderObject* renderer = textNode.renderer(); 974 if (renderer && !renderer->style().collapseWhiteSpace()) 975 return; 976 } 971 977 972 978 // Delete collapsed whitespace so that inserting nbsps doesn't uncollapse it. … … 1003 1009 document().updateLayout(); 1004 1010 1005 RenderText* textRenderer = textNode.renderer(); 1006 if (!textRenderer) 1007 return; 1008 1009 auto run = LayoutIntegration::firstTextRunInTextOrderFor(*textRenderer); 1010 if (!run) { 1011 // whole text node is empty 1011 bool wholeTextNodeIsEmpty = false; 1012 String str; 1013 auto determineRemovalMode = [&] { 1014 ScriptDisallowedScope::InMainThread scriptDisallowedScope; 1015 RenderText* textRenderer = textNode.renderer(); 1016 if (!textRenderer) 1017 return; 1018 1019 auto run = LayoutIntegration::firstTextRunInTextOrderFor(*textRenderer); 1020 if (!run) { 1021 wholeTextNodeIsEmpty = true; 1022 return; 1023 } 1024 1025 unsigned length = textNode.length(); 1026 if (start >= length || end > length) 1027 return; 1028 1029 unsigned removed = 0; 1030 LayoutIntegration::TextRunIterator previousRun; 1031 1032 // This loop structure works to process all gaps preceding a box, 1033 // and also will look at the gap after the last box. 1034 while (previousRun || run) { 1035 unsigned gapStart = previousRun ? previousRun->end() : 0; 1036 if (end < gapStart) 1037 break; // No more chance for any intersections 1038 1039 unsigned gapEnd = run ? run->start() : length; 1040 bool indicesIntersect = start <= gapEnd && end >= gapStart; 1041 int gapLen = gapEnd - gapStart; 1042 if (indicesIntersect && gapLen > 0) { 1043 gapStart = std::max(gapStart, start); 1044 gapEnd = std::min(gapEnd, end); 1045 if (str.isNull()) 1046 str = textNode.data().substring(start, end - start); 1047 // remove text in the gap 1048 str.remove(gapStart - start - removed, gapLen); 1049 removed += gapLen; 1050 } 1051 1052 previousRun = run; 1053 if (run) 1054 run.traverseNextTextRunInTextOrder(); 1055 } 1056 }; 1057 determineRemovalMode(); 1058 1059 if (wholeTextNodeIsEmpty) { 1012 1060 removeNode(textNode); 1013 return; 1014 } 1015 1016 unsigned length = textNode.length(); 1017 if (start >= length || end > length) 1018 return; 1019 1020 unsigned removed = 0; 1021 LayoutIntegration::TextRunIterator previousRun; 1022 String str; 1023 1024 // This loop structure works to process all gaps preceding a box, 1025 // and also will look at the gap after the last box. 1026 while (previousRun || run) { 1027 unsigned gapStart = previousRun ? previousRun->end() : 0; 1028 if (end < gapStart) 1029 // No more chance for any intersections 1030 break; 1031 1032 unsigned gapEnd = run ? run->start() : length; 1033 bool indicesIntersect = start <= gapEnd && end >= gapStart; 1034 int gapLen = gapEnd - gapStart; 1035 if (indicesIntersect && gapLen > 0) { 1036 gapStart = std::max(gapStart, start); 1037 gapEnd = std::min(gapEnd, end); 1038 if (str.isNull()) 1039 str = textNode.data().substring(start, end - start); 1040 // remove text in the gap 1041 str.remove(gapStart - start - removed, gapLen); 1042 removed += gapLen; 1043 } 1044 1045 previousRun = run; 1046 if (run) 1047 run.traverseNextTextRunInTextOrder(); 1061 return; 1048 1062 } 1049 1063 … … 1120 1134 document().updateLayoutIgnorePendingStylesheets(); 1121 1135 1122 auto* renderer = container->renderer(); 1123 if (!is<RenderBlockFlow>(renderer)) 1124 return nullptr; 1125 1126 // Append the placeholder to make sure it follows any unrendered blocks. 1127 auto& blockFlow = downcast<RenderBlockFlow>(*renderer); 1128 if (!blockFlow.height() || (blockFlow.isListItem() && !blockFlow.firstChild())) 1129 return appendBlockPlaceholder(*container); 1130 1131 return nullptr; 1136 { 1137 ScriptDisallowedScope::InMainThread scriptDisallowedScope; 1138 1139 auto* renderer = container->renderer(); 1140 if (!is<RenderBlockFlow>(renderer)) 1141 return nullptr; 1142 1143 // Append the placeholder to make sure it follows any unrendered blocks. 1144 auto& blockFlow = downcast<RenderBlockFlow>(*renderer); 1145 if (blockFlow.height() && (!blockFlow.isListItem() || blockFlow.firstChild())) 1146 return nullptr; 1147 } 1148 1149 return appendBlockPlaceholder(*container); 1132 1150 } 1133 1151 … … 1262 1280 1263 1281 for (size_t i = ancestors.size(); i != 0; --i) { 1264 Node* item = ancestors[i - 1].get();1265 auto child = item->cloneNode(isRenderedTable(item ));1282 auto item = std::exchange(ancestors[i - 1], nullptr); 1283 auto child = item->cloneNode(isRenderedTable(item.get())); 1266 1284 appendNode(child.copyRef(), downcast<Element>(*lastNode)); 1267 1285 lastNode = WTFMove(child); … … 1553 1571 1554 1572 RefPtr<Element> newBlock; 1555 if ( ContainerNode* blockEnclosingList = listNode->parentNode()) {1573 if (auto blockEnclosingList = makeRefPtr(listNode->parentNode())) { 1556 1574 if (is<HTMLLIElement>(*blockEnclosingList)) { // listNode is inside another list item 1557 1575 if (visiblePositionAfterNode(*blockEnclosingList) == visiblePositionAfterNode(*listNode)) { … … 1608 1626 1609 1627 VisiblePosition caret(endingSelection().visibleStart()); 1610 Node* highestBlockquote = highestEnclosingNodeOfType(caret.deepEquivalent(), &isMailBlockquote);1628 auto highestBlockquote = makeRefPtr(highestEnclosingNodeOfType(caret.deepEquivalent(), &isMailBlockquote)); 1611 1629 if (!highestBlockquote) 1612 1630 return false; … … 1621 1639 1622 1640 auto br = HTMLBRElement::create(document()); 1623 auto* brPtr = br.ptr();1624 1641 // We want to replace this quoted paragraph with an unquoted one, so insert a br 1625 1642 // to hold the caret before the highest blockquote. 1626 insertNodeBefore(br .copyRef(), *highestBlockquote);1627 VisiblePosition atBR (positionBeforeNode(brPtr));1643 insertNodeBefore(br, *highestBlockquote); 1644 VisiblePosition atBR = positionBeforeNode(br.ptr()); 1628 1645 // If the br we inserted collapsed, for example foo<br><blockquote>...</blockquote>, insert 1629 1646 // a second one. 1630 1647 if (!isStartOfParagraph(atBR)) 1631 insertNodeBefore(HTMLBRElement::create(document()), *brPtr);1648 insertNodeBefore(HTMLBRElement::create(document()), br.get()); 1632 1649 setEndingSelection(VisibleSelection(atBR, endingSelection().isDirectional())); 1633 1650 … … 1665 1682 1666 1683 VisiblePosition visiblePos(original); 1667 Element* enclosingAnchor = enclosingAnchorElement(original);1684 auto enclosingAnchor = makeRefPtr(enclosingAnchorElement(original)); 1668 1685 Position result = original; 1669 1686 … … 1672 1689 1673 1690 // Don't avoid block level anchors, because that would insert content into the wrong paragraph. 1674 if (enclosingAnchor && !isBlock(enclosingAnchor )) {1675 VisiblePosition firstInAnchor(firstPositionInNode(enclosingAnchor ));1676 VisiblePosition lastInAnchor(lastPositionInNode(enclosingAnchor ));1691 if (enclosingAnchor && !isBlock(enclosingAnchor.get())) { 1692 VisiblePosition firstInAnchor(firstPositionInNode(enclosingAnchor.get())); 1693 VisiblePosition lastInAnchor(lastPositionInNode(enclosingAnchor.get())); 1677 1694 // If visually just after the anchor, insert *inside* the anchor unless it's the last 1678 1695 // VisiblePosition in the document, to match NSTextView. … … 1689 1706 // probably be safe to move the line break so that we could still avoid the anchor here. 1690 1707 Position downstream(visiblePos.deepEquivalent().downstream()); 1691 if (lineBreakExistsAtVisiblePosition(visiblePos) && downstream.deprecatedNode()->isDescendantOf(enclosingAnchor ))1708 if (lineBreakExistsAtVisiblePosition(visiblePos) && downstream.deprecatedNode()->isDescendantOf(enclosingAnchor.get())) 1692 1709 return original; 1693 1710 1694 result = positionInParentAfterNode(enclosingAnchor );1711 result = positionInParentAfterNode(enclosingAnchor.get()); 1695 1712 } 1696 1713 // If visually just before an anchor, insert *outside* the anchor unless it's the first … … 1706 1723 return original; 1707 1724 1708 result = positionInParentBeforeNode(enclosingAnchor );1725 result = positionInParentBeforeNode(enclosingAnchor.get()); 1709 1726 } 1710 1727 } -
trunk/Source/WebCore/editing/CompositeEditCommand.h
r275498 r276131 31 31 #include "UndoStep.h" 32 32 #include <wtf/Vector.h> 33 #include <wtf/WeakPtr.h> 33 34 34 35 namespace WebCore { … … 104 105 }; 105 106 106 class CompositeEditCommand : public EditCommand {107 class CompositeEditCommand : public EditCommand, public CanMakeWeakPtr<CompositeEditCommand> { 107 108 public: 108 109 virtual ~CompositeEditCommand(); … … 164 165 void rebalanceWhitespaceOnTextSubstring(Text&, int startOffset, int endOffset); 165 166 void prepareWhitespaceAtPositionForSplit(Position&); 166 bool canRebalance(const Position&) const;167 RefPtr<Text> textNodeForRebalance(const Position&) const; 167 168 bool shouldRebalanceLeadingWhitespaceFor(const String&) const; 168 169 void removeNodeAttribute(Element&, const QualifiedName& attribute); … … 222 223 }; 223 224 224 inline CompositeEditCommand* toCompositeEditCommand(EditCommand* command)225 {226 ASSERT(command);227 ASSERT_WITH_SECURITY_IMPLICATION(command->isCompositeEditCommand());228 return static_cast<CompositeEditCommand*>(command);229 }230 231 225 } // namespace WebCore -
trunk/Source/WebCore/editing/EditCommand.cpp
r260831 r276131 33 33 #include "Editor.h" 34 34 #include "Element.h" 35 #include "HTMLInputElement.h" 36 #include "HTMLTextAreaElement.h" 35 #include "HTMLTextFormControlElement.h" 37 36 #include "NodeTraversal.h" 38 37 … … 124 123 125 124 EditCommand::EditCommand(Document& document, EditAction editingAction) 126 : m_document (document)127 , m_ editingAction(editingAction)128 { 129 setStartingSelection(m_document->selection().selection());130 setEndingSelection(m_startingSelection); 125 : m_document { document } 126 , m_startingSelection { m_document->selection().selection() } 127 , m_endingSelection { m_startingSelection } 128 , m_editingAction { editingAction } 129 { 131 130 } 132 131 133 132 EditCommand::EditCommand(Document& document, const VisibleSelection& startingSelection, const VisibleSelection& endingSelection) 134 : m_document (document)135 { 136 setStartingSelection(startingSelection);137 setEndingSelection(endingSelection); 133 : m_document { document } 134 , m_startingSelection { startingSelection } 135 , m_endingSelection { endingSelection } 136 { 138 137 } 139 138 … … 145 144 } 146 145 147 static inline EditCommandComposition* compositionIfPossible(EditCommand*command)148 { 149 if (!command ->isCompositeEditCommand())150 return 0;151 return toCompositeEditCommand(command)->composition();146 static RefPtr<EditCommandComposition> compositionIfPossible(EditCommand& command) 147 { 148 if (!command.isCompositeEditCommand()) 149 return nullptr; 150 return static_cast<CompositeEditCommand&>(command).composition(); 152 151 } 153 152 154 153 bool EditCommand::isEditingTextAreaOrTextInput() const 155 154 { 156 auto* container = m_document->selection().selection().start().containerNode(); 157 if (!container) 158 return false; 159 160 auto* ancestor = container->shadowHost(); 161 if (!ancestor) 162 return false; 163 164 return is<HTMLTextAreaElement>(*ancestor) || (is<HTMLInputElement>(*ancestor) && downcast<HTMLInputElement>(*ancestor).isText()); 165 } 166 167 void EditCommand::setStartingSelection(const VisibleSelection& s) 168 { 169 for (EditCommand* cmd = this; ; cmd = cmd->m_parent) { 170 if (auto* composition = compositionIfPossible(cmd)) 171 composition->setStartingSelection(s); 172 cmd->m_startingSelection = s; 173 if (!cmd->m_parent || cmd->m_parent->isFirstCommand(cmd)) 155 return enclosingTextFormControl(m_document->selection().selection().start()); 156 } 157 158 void EditCommand::setStartingSelection(const VisibleSelection& selection) 159 { 160 for (auto command = makeRefPtr(this); ; command = command->m_parent.get()) { 161 if (auto composition = compositionIfPossible(*command)) 162 composition->setStartingSelection(selection); 163 command->m_startingSelection = selection; 164 if (!command->m_parent || command->m_parent->isFirstCommand(command.get())) 174 165 break; 175 166 } 176 167 } 177 168 178 void EditCommand::setEndingSelection(const VisibleSelection &s)179 { 180 for ( EditCommand* cmd = this; cmd; cmd = cmd->m_parent) {181 if (auto * composition = compositionIfPossible(cmd))182 composition->setEndingSelection(s );183 c md->m_endingSelection = s;169 void EditCommand::setEndingSelection(const VisibleSelection& selection) 170 { 171 for (auto command = makeRefPtr(this); command; command = command->m_parent.get()) { 172 if (auto composition = compositionIfPossible(*command)) 173 composition->setEndingSelection(selection); 174 command->m_endingSelection = selection; 184 175 } 185 176 } … … 188 179 { 189 180 ASSERT((parent && !m_parent) || (!parent && m_parent)); 190 m_parent = parent;181 m_parent = makeWeakPtr(parent); 191 182 if (parent) { 192 183 m_startingSelection = parent->m_endingSelection; … … 211 202 if (!cache) 212 203 return; 213 auto * node = highestEditableRoot(position.deepEquivalent(), HasEditableAXRole);214 cache->postTextStateChangeNotification(node , type, text, position);204 auto node = makeRefPtr(highestEditableRoot(position.deepEquivalent(), HasEditableAXRole)); 205 cache->postTextStateChangeNotification(node.get(), type, text, position); 215 206 } 216 207 -
trunk/Source/WebCore/editing/EditCommand.h
r260831 r276131 29 29 #include "EditAction.h" 30 30 #include "VisibleSelection.h" 31 #include <wtf/WeakPtr.h> 31 32 32 33 #ifndef NDEBUG … … 66 67 const Document& document() const { return m_document; } 67 68 Document& document() { return m_document; } 68 CompositeEditCommand* parent() const { return m_parent ; }69 CompositeEditCommand* parent() const { return m_parent.get(); } 69 70 void setStartingSelection(const VisibleSelection&); 70 71 WEBCORE_EXPORT void setEndingSelection(const VisibleSelection&); … … 79 80 VisibleSelection m_startingSelection; 80 81 VisibleSelection m_endingSelection; 81 CompositeEditCommand* m_parent { nullptr };82 WeakPtr<CompositeEditCommand> m_parent; 82 83 EditAction m_editingAction { EditAction::Unspecified }; 83 84 }; -
trunk/Source/WebCore/editing/InsertTextCommand.cpp
r266557 r276131 215 215 } else { 216 216 ASSERT(m_rebalanceType == RebalanceAllWhitespaces); 217 if (canRebalance(startPosition) && canRebalance(endPosition)) 217 ASSERT(textNodeForRebalance(startPosition) == textNodeForRebalance(endPosition)); 218 if (auto textForRebalance = textNodeForRebalance(startPosition)) { 219 ASSERT(textForRebalance == textNode); 218 220 rebalanceWhitespaceOnTextSubstring(*textNode, startPosition.offsetInContainerNode(), endPosition.offsetInContainerNode()); 221 } 222 219 223 } 220 224 }
Note:
See TracChangeset
for help on using the changeset viewer.