OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 | 139 |
140 if (nextPosition == pos | 140 if (nextPosition == pos |
141 || enclosingBlock(nextPosition.computeContainerNode()) != enclosingB
lockElement | 141 || enclosingBlock(nextPosition.computeContainerNode()) != enclosingB
lockElement |
142 || VisiblePosition(pos).deepEquivalent() != VisiblePosition(nextPosi
tion).deepEquivalent()) | 142 || VisiblePosition(pos).deepEquivalent() != VisiblePosition(nextPosi
tion).deepEquivalent()) |
143 break; | 143 break; |
144 } | 144 } |
145 return pos; | 145 return pos; |
146 } | 146 } |
147 | 147 |
148 ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
ragment, const VisibleSelection& selection) | 148 ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
ragment, const VisibleSelection& selection) |
149 : m_document(document), | 149 : m_document(document) |
150 m_fragment(fragment), | 150 , m_fragment(fragment) |
151 m_hasInterchangeNewlineAtStart(false), | 151 , m_hasInterchangeNewlineAtStart(false) |
152 m_hasInterchangeNewlineAtEnd(false) | 152 , m_hasInterchangeNewlineAtEnd(false) |
153 { | 153 { |
154 if (!m_document) | 154 if (!m_document) |
155 return; | 155 return; |
156 if (!m_fragment || !m_fragment->hasChildren()) | 156 if (!m_fragment || !m_fragment->hasChildren()) |
157 return; | 157 return; |
158 | 158 |
159 RefPtrWillBeRawPtr<Element> editableRoot = selection.rootEditableElement(); | 159 RefPtrWillBeRawPtr<Element> editableRoot = selection.rootEditableElement(); |
160 ASSERT(editableRoot); | 160 ASSERT(editableRoot); |
161 if (!editableRoot) | 161 if (!editableRoot) |
162 return; | 162 return; |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().an
chorNode()); | 852 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().an
chorNode()); |
853 destination = VisiblePosition(positionBeforeNode(placeholder.get())); | 853 destination = VisiblePosition(positionBeforeNode(placeholder.get())); |
854 } | 854 } |
855 | 855 |
856 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove)
, destination); | 856 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove)
, destination); |
857 | 857 |
858 // Merging forward will remove m_endOfInsertedContent from the document. | 858 // Merging forward will remove m_endOfInsertedContent from the document. |
859 if (mergeForward) { | 859 if (mergeForward) { |
860 if (m_startOfInsertedContent.isOrphan()) | 860 if (m_startOfInsertedContent.isOrphan()) |
861 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui
valent(); | 861 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui
valent(); |
862 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivalent(
); | 862 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivalent()
; |
863 // If we merged text nodes, m_endOfInsertedContent could be null. If thi
s is the case, we use m_startOfInsertedContent. | 863 // If we merged text nodes, m_endOfInsertedContent could be null. If |
| 864 // this is the case, we use m_startOfInsertedContent. |
864 if (m_endOfInsertedContent.isNull()) | 865 if (m_endOfInsertedContent.isNull()) |
865 m_endOfInsertedContent = m_startOfInsertedContent; | 866 m_endOfInsertedContent = m_startOfInsertedContent; |
866 } | 867 } |
867 } | 868 } |
868 | 869 |
869 static Node* enclosingInline(Node* node) | 870 static Node* enclosingInline(Node* node) |
870 { | 871 { |
871 while (ContainerNode* parent = node->parentNode()) { | 872 while (ContainerNode* parent = node->parentNode()) { |
872 if (isBlockFlowElement(*parent) || isHTMLBodyElement(*parent)) | 873 if (isBlockFlowElement(*parent) || isHTMLBodyElement(*parent)) |
873 return node; | 874 return node; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd); | 948 bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd); |
948 bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart); | 949 bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart); |
949 | 950 |
950 Element* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEqui
valent().anchorNode()); | 951 Element* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEqui
valent().anchorNode()); |
951 | 952 |
952 Position insertionPos = selection.start(); | 953 Position insertionPos = selection.start(); |
953 bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailH
TMLBlockquoteElement, CanCrossEditingBoundary); | 954 bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailH
TMLBlockquoteElement, CanCrossEditingBoundary); |
954 bool selectionIsPlainText = !selection.isContentRichlyEditable(); | 955 bool selectionIsPlainText = !selection.isContentRichlyEditable(); |
955 Element* currentRoot = selection.rootEditableElement(); | 956 Element* currentRoot = selection.rootEditableElement(); |
956 | 957 |
957 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && !
startIsInsideMailBlockquote) || | 958 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && !
startIsInsideMailBlockquote) |
958 enclosingBlockOfVisibleStart == currentRoot || isListItem(enclosingBlock
OfVisibleStart) || selectionIsPlainText) | 959 || enclosingBlockOfVisibleStart == currentRoot |
| 960 || isListItem(enclosingBlockOfVisibleStart) |
| 961 || selectionIsPlainText) { |
959 m_preventNesting = false; | 962 m_preventNesting = false; |
| 963 } |
960 | 964 |
961 if (selection.isRange()) { | 965 if (selection.isRange()) { |
962 // When the end of the selection being pasted into is at the end of a pa
ragraph, and that selection | 966 // When the end of the selection being pasted into is at the end of a pa
ragraph, and that selection |
963 // spans multiple blocks, not merging may leave an empty line. | 967 // spans multiple blocks, not merging may leave an empty line. |
964 // When the start of the selection being pasted into is at the start of
a block, not merging | 968 // When the start of the selection being pasted into is at the start of
a block, not merging |
965 // will leave hanging block(s). | 969 // will leave hanging block(s). |
966 // Merge blocks if the start of the selection was in a Mail blockquote,
since we handle | 970 // Merge blocks if the start of the selection was in a Mail blockquote,
since we handle |
967 // that case specially to prevent nesting. | 971 // that case specially to prevent nesting. |
968 bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfPara
graph(visibleEnd) || isStartOfBlock(visibleStart); | 972 bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfPara
graph(visibleEnd) || isStartOfBlock(visibleStart); |
969 // FIXME: We should only expand to include fully selected special elemen
ts if we are copying a | 973 // FIXME: We should only expand to include fully selected special elemen
ts if we are copying a |
970 // selection and pasting it on top of itself. | 974 // selection and pasting it on top of itself. |
971 deleteSelection(false, mergeBlocksAfterDelete, false); | 975 deleteSelection(false, mergeBlocksAfterDelete, false); |
972 visibleStart = endingSelection().visibleStart(); | 976 visibleStart = endingSelection().visibleStart(); |
973 if (fragment.hasInterchangeNewlineAtStart()) { | 977 if (fragment.hasInterchangeNewlineAtStart()) { |
974 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt)) { | 978 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt)) { |
975 if (!isEndOfEditableOrNonEditableContent(visibleStart)) | 979 if (!isEndOfEditableOrNonEditableContent(visibleStart)) |
976 setEndingSelection(visibleStart.next()); | 980 setEndingSelection(visibleStart.next()); |
977 } else | 981 } else { |
978 insertParagraphSeparator(); | 982 insertParagraphSeparator(); |
| 983 } |
979 } | 984 } |
980 insertionPos = endingSelection().start(); | 985 insertionPos = endingSelection().start(); |
981 } else { | 986 } else { |
982 ASSERT(selection.isCaret()); | 987 ASSERT(selection.isCaret()); |
983 if (fragment.hasInterchangeNewlineAtStart()) { | 988 if (fragment.hasInterchangeNewlineAtStart()) { |
984 VisiblePosition next = visibleStart.next(CannotCrossEditingBoundary)
; | 989 VisiblePosition next = visibleStart.next(CannotCrossEditingBoundary)
; |
985 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt) && next.isNotNull()) | 990 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt) && next.isNotNull()) { |
986 setEndingSelection(next); | 991 setEndingSelection(next); |
987 else { | 992 } else { |
988 insertParagraphSeparator(); | 993 insertParagraphSeparator(); |
989 visibleStart = endingSelection().visibleStart(); | 994 visibleStart = endingSelection().visibleStart(); |
990 } | 995 } |
991 } | 996 } |
992 // We split the current paragraph in two to avoid nesting the blocks fro
m the fragment inside the current block. | 997 // We split the current paragraph in two to avoid nesting the blocks fro
m the fragment inside the current block. |
993 // For example paste <div>foo</div><div>bar</div><div>baz</div> into <di
v>x^x</div>, where ^ is the caret. | 998 // For example paste <div>foo</div><div>bar</div><div>baz</div> into <di
v>x^x</div>, where ^ is the caret. |
994 // As long as the div styles are the same, visually you'd expect: <div>
xbar</div><div>bar</div><div>bazx</div>, | 999 // As long as the div styles are the same, visually you'd expect: <div>
xbar</div><div>bar</div><div>bazx</div>, |
995 // not <div>xbar<div>bar</div><div>bazx</div></div>. | 1000 // not <div>xbar<div>bar</div><div>bazx</div></div>. |
996 // Don't do this if the selection started in a Mail blockquote. | 1001 // Don't do this if the selection started in a Mail blockquote. |
997 if (m_preventNesting && !startIsInsideMailBlockquote && !isEndOfParagrap
h(visibleStart) && !isStartOfParagraph(visibleStart)) { | 1002 if (m_preventNesting && !startIsInsideMailBlockquote && !isEndOfParagrap
h(visibleStart) && !isStartOfParagraph(visibleStart)) { |
(...skipping 14 matching lines...) Expand all Loading... |
1012 // Insert content between the two blockquotes, but remove the br (since
it was just a placeholder). | 1017 // Insert content between the two blockquotes, but remove the br (since
it was just a placeholder). |
1013 insertionPos = positionInParentBeforeNode(*br); | 1018 insertionPos = positionInParentBeforeNode(*br); |
1014 removeNode(br); | 1019 removeNode(br); |
1015 } | 1020 } |
1016 | 1021 |
1017 // Inserting content could cause whitespace to collapse, e.g. inserting <div
>foo</div> into hello^ world. | 1022 // Inserting content could cause whitespace to collapse, e.g. inserting <div
>foo</div> into hello^ world. |
1018 prepareWhitespaceAtPositionForSplit(insertionPos); | 1023 prepareWhitespaceAtPositionForSplit(insertionPos); |
1019 | 1024 |
1020 // If the downstream node has been removed there's no point in continuing. | 1025 // If the downstream node has been removed there's no point in continuing. |
1021 if (!insertionPos.downstream().anchorNode()) | 1026 if (!insertionPos.downstream().anchorNode()) |
1022 return; | 1027 return; |
1023 | 1028 |
1024 // NOTE: This would be an incorrect usage of downstream() if downstream() we
re changed to mean the last position after | 1029 // NOTE: This would be an incorrect usage of downstream() if downstream() we
re changed to mean the last position after |
1025 // p that maps to the same visible position as p (since in the case where a
br is at the end of a block and collapsed | 1030 // p that maps to the same visible position as p (since in the case where a
br is at the end of a block and collapsed |
1026 // away, there are positions after the br which map to the same visible posi
tion as [br, 0]). | 1031 // away, there are positions after the br which map to the same visible posi
tion as [br, 0]). |
1027 HTMLBRElement* endBR = isHTMLBRElement(*insertionPos.downstream().anchorNode
()) ? toHTMLBRElement(insertionPos.downstream().anchorNode()) : 0; | 1032 HTMLBRElement* endBR = isHTMLBRElement(*insertionPos.downstream().anchorNode
()) ? toHTMLBRElement(insertionPos.downstream().anchorNode()) : 0; |
1028 VisiblePosition originalVisPosBeforeEndBR; | 1033 VisiblePosition originalVisPosBeforeEndBR; |
1029 if (endBR) | 1034 if (endBR) |
1030 originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), D
OWNSTREAM).previous(); | 1035 originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), D
OWNSTREAM).previous(); |
1031 | 1036 |
1032 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in
sertionPos.anchorNode()); | 1037 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in
sertionPos.anchorNode()); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1104 | 1109 |
1105 InsertedNodes insertedNodes; | 1110 InsertedNodes insertedNodes; |
1106 RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild(); | 1111 RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild(); |
1107 ASSERT(refNode); | 1112 ASSERT(refNode); |
1108 RefPtrWillBeRawPtr<Node> node = refNode->nextSibling(); | 1113 RefPtrWillBeRawPtr<Node> node = refNode->nextSibling(); |
1109 | 1114 |
1110 fragment.removeNode(refNode); | 1115 fragment.removeNode(refNode); |
1111 | 1116 |
1112 Element* blockStart = enclosingBlock(insertionPos.anchorNode()); | 1117 Element* blockStart = enclosingBlock(insertionPos.anchorNode()); |
1113 if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNo
de.get()) && isHTMLListElement(refNode->firstChild()))) | 1118 if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNo
de.get()) && isHTMLListElement(refNode->firstChild()))) |
1114 && blockStart && blockStart->layoutObject()->isListItem()) | 1119 && blockStart && blockStart->layoutObject()->isListItem()) { |
1115 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio
nPos, insertedNodes); | 1120 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio
nPos, insertedNodes); |
1116 else { | 1121 } else { |
1117 insertNodeAt(refNode, insertionPos); | 1122 insertNodeAt(refNode, insertionPos); |
1118 insertedNodes.respondToNodeInsertion(*refNode); | 1123 insertedNodes.respondToNodeInsertion(*refNode); |
1119 } | 1124 } |
1120 | 1125 |
1121 // Mutation events (bug 22634) may have already removed the inserted content | 1126 // Mutation events (bug 22634) may have already removed the inserted content |
1122 if (!refNode->inDocument()) | 1127 if (!refNode->inDocument()) |
1123 return; | 1128 return; |
1124 | 1129 |
1125 bool plainTextFragment = isPlainTextMarkup(refNode.get()); | 1130 bool plainTextFragment = isPlainTextMarkup(refNode.get()); |
1126 | 1131 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1369 | 1374 |
1370 if (m_matchStyle) { | 1375 if (m_matchStyle) { |
1371 ASSERT(m_insertionStyle); | 1376 ASSERT(m_insertionStyle); |
1372 applyStyle(m_insertionStyle.get(), start, end); | 1377 applyStyle(m_insertionStyle.get(), start, end); |
1373 } | 1378 } |
1374 | 1379 |
1375 if (lastPositionToSelect.isNotNull()) | 1380 if (lastPositionToSelect.isNotNull()) |
1376 end = lastPositionToSelect; | 1381 end = lastPositionToSelect; |
1377 | 1382 |
1378 mergeTextNodesAroundPosition(start, end); | 1383 mergeTextNodesAroundPosition(start, end); |
1379 } else if (lastPositionToSelect.isNotNull()) | 1384 } else if (lastPositionToSelect.isNotNull()) { |
1380 start = end = lastPositionToSelect; | 1385 start = end = lastPositionToSelect; |
1381 else | 1386 } else { |
1382 return; | 1387 return; |
| 1388 } |
1383 | 1389 |
1384 if (m_selectReplacement) | 1390 if (m_selectReplacement) |
1385 setEndingSelection(VisibleSelection(start, end, SEL_DEFAULT_AFFINITY, en
dingSelection().isDirectional())); | 1391 setEndingSelection(VisibleSelection(start, end, SEL_DEFAULT_AFFINITY, en
dingSelection().isDirectional())); |
1386 else | 1392 else |
1387 setEndingSelection(VisibleSelection(end, SEL_DEFAULT_AFFINITY, endingSel
ection().isDirectional())); | 1393 setEndingSelection(VisibleSelection(end, SEL_DEFAULT_AFFINITY, endingSel
ection().isDirectional())); |
1388 } | 1394 } |
1389 | 1395 |
1390 void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P
osition& positionOnlyToBeUpdated) | 1396 void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P
osition& positionOnlyToBeUpdated) |
1391 { | 1397 { |
1392 bool positionIsOffsetInAnchor = position.isOffsetInAnchor(); | 1398 bool positionIsOffsetInAnchor = position.isOffsetInAnchor(); |
1393 bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.isOff
setInAnchor(); | 1399 bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.isOff
setInAnchor(); |
1394 RefPtrWillBeRawPtr<Text> text = nullptr; | 1400 RefPtrWillBeRawPtr<Text> text = nullptr; |
1395 if (positionIsOffsetInAnchor && position.computeContainerNode() && position.
computeContainerNode()->isTextNode()) | 1401 if (positionIsOffsetInAnchor && position.computeContainerNode() && position.
computeContainerNode()->isTextNode()) { |
1396 text = toText(position.computeContainerNode()); | 1402 text = toText(position.computeContainerNode()); |
1397 else { | 1403 } else { |
1398 Node* before = position.computeNodeBeforePosition(); | 1404 Node* before = position.computeNodeBeforePosition(); |
1399 if (before && before->isTextNode()) | 1405 if (before && before->isTextNode()) { |
1400 text = toText(before); | 1406 text = toText(before); |
1401 else { | 1407 } else { |
1402 Node* after = position.computeNodeAfterPosition(); | 1408 Node* after = position.computeNodeAfterPosition(); |
1403 if (after && after->isTextNode()) | 1409 if (after && after->isTextNode()) |
1404 text = toText(after); | 1410 text = toText(after); |
1405 } | 1411 } |
1406 } | 1412 } |
1407 if (!text) | 1413 if (!text) |
1408 return; | 1414 return; |
1409 | 1415 |
1410 if (text->previousSibling() && text->previousSibling()->isTextNode()) { | 1416 if (text->previousSibling() && text->previousSibling()->isTextNode()) { |
1411 RefPtrWillBeRawPtr<Text> previous = toText(text->previousSibling()); | 1417 RefPtrWillBeRawPtr<Text> previous = toText(text->previousSibling()); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1474 | 1480 |
1475 while (RefPtrWillBeRawPtr<Node> listItem = listElement->firstChild()) { | 1481 while (RefPtrWillBeRawPtr<Node> listItem = listElement->firstChild()) { |
1476 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION); | 1482 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION); |
1477 if (isStart || isMiddle) { | 1483 if (isStart || isMiddle) { |
1478 insertNodeBefore(listItem, lastNode); | 1484 insertNodeBefore(listItem, lastNode); |
1479 insertedNodes.respondToNodeInsertion(*listItem); | 1485 insertedNodes.respondToNodeInsertion(*listItem); |
1480 } else if (isEnd) { | 1486 } else if (isEnd) { |
1481 insertNodeAfter(listItem, lastNode); | 1487 insertNodeAfter(listItem, lastNode); |
1482 insertedNodes.respondToNodeInsertion(*listItem); | 1488 insertedNodes.respondToNodeInsertion(*listItem); |
1483 lastNode = listItem.get(); | 1489 lastNode = listItem.get(); |
1484 } else | 1490 } else { |
1485 ASSERT_NOT_REACHED(); | 1491 ASSERT_NOT_REACHED(); |
| 1492 } |
1486 } | 1493 } |
1487 if (isStart || isMiddle) { | 1494 if (isStart || isMiddle) { |
1488 if (Node* node = lastNode->previousSibling()) | 1495 if (Node* node = lastNode->previousSibling()) |
1489 return node; | 1496 return node; |
1490 } | 1497 } |
1491 return lastNode; | 1498 return lastNode; |
1492 } | 1499 } |
1493 | 1500 |
1494 void ReplaceSelectionCommand::updateNodesInserted(Node *node) | 1501 void ReplaceSelectionCommand::updateNodesInserted(Node *node) |
1495 { | 1502 { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 DEFINE_TRACE(ReplaceSelectionCommand) | 1549 DEFINE_TRACE(ReplaceSelectionCommand) |
1543 { | 1550 { |
1544 visitor->trace(m_startOfInsertedContent); | 1551 visitor->trace(m_startOfInsertedContent); |
1545 visitor->trace(m_endOfInsertedContent); | 1552 visitor->trace(m_endOfInsertedContent); |
1546 visitor->trace(m_insertionStyle); | 1553 visitor->trace(m_insertionStyle); |
1547 visitor->trace(m_documentFragment); | 1554 visitor->trace(m_documentFragment); |
1548 CompositeEditCommand::trace(visitor); | 1555 CompositeEditCommand::trace(visitor); |
1549 } | 1556 } |
1550 | 1557 |
1551 } // namespace blink | 1558 } // namespace blink |
OLD | NEW |