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 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 #include "HTMLInputElement.h" | 43 #include "HTMLInputElement.h" |
44 #include "HTMLInterchange.h" | 44 #include "HTMLInterchange.h" |
45 #include "HTMLNames.h" | 45 #include "HTMLNames.h" |
46 #include "SelectionController.h" | 46 #include "SelectionController.h" |
47 #include "SmartReplace.h" | 47 #include "SmartReplace.h" |
48 #include "TextIterator.h" | 48 #include "TextIterator.h" |
49 #include "htmlediting.h" | 49 #include "htmlediting.h" |
50 #include "markup.h" | 50 #include "markup.h" |
51 #include "visible_units.h" | 51 #include "visible_units.h" |
52 #include <wtf/StdLibExtras.h> | 52 #include <wtf/StdLibExtras.h> |
| 53 #include <wtf/Vector.h> |
53 | 54 |
54 namespace WebCore { | 55 namespace WebCore { |
55 | 56 |
| 57 typedef Vector<RefPtr<Node> > NodeVector; |
| 58 |
56 using namespace HTMLNames; | 59 using namespace HTMLNames; |
57 | 60 |
58 enum EFragmentType { EmptyFragment, SingleTextNodeFragment, TreeFragment }; | 61 enum EFragmentType { EmptyFragment, SingleTextNodeFragment, TreeFragment }; |
59 | 62 |
60 // --- ReplacementFragment helper class | 63 // --- ReplacementFragment helper class |
61 | 64 |
62 class ReplacementFragment : public Noncopyable { | 65 class ReplacementFragment : public Noncopyable { |
63 public: | 66 public: |
64 ReplacementFragment(Document*, DocumentFragment*, bool matchStyle, const Vis
ibleSelection&); | 67 ReplacementFragment(Document*, DocumentFragment*, bool matchStyle, const Vis
ibleSelection&); |
65 | 68 |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 // appears redundant. | 678 // appears redundant. |
676 setNodeAttribute(static_cast<Element*>(copiedRangeStyleSpan), styleAttr, cop
iedRangeStyle->style()->cssText()); | 679 setNodeAttribute(static_cast<Element*>(copiedRangeStyleSpan), styleAttr, cop
iedRangeStyle->style()->cssText()); |
677 } | 680 } |
678 | 681 |
679 // Take the style attribute of a span and apply it to it's children instead. Th
is allows us to | 682 // Take the style attribute of a span and apply it to it's children instead. Th
is allows us to |
680 // convert invalid HTML where a span contains block elements into valid HTML whi
le preserving | 683 // convert invalid HTML where a span contains block elements into valid HTML whi
le preserving |
681 // styles. | 684 // styles. |
682 void ReplaceSelectionCommand::copyStyleToChildren(Node* parentNode, const CSSMut
ableStyleDeclaration* parentStyle) | 685 void ReplaceSelectionCommand::copyStyleToChildren(Node* parentNode, const CSSMut
ableStyleDeclaration* parentStyle) |
683 { | 686 { |
684 ASSERT(parentNode->hasTagName(spanTag)); | 687 ASSERT(parentNode->hasTagName(spanTag)); |
685 for (Node* childNode = parentNode->firstChild(); childNode; childNode = chil
dNode->nextSibling()) { | 688 NodeVector childNodes; |
| 689 for (RefPtr<Node> childNode = parentNode->firstChild(); childNode; childNode
= childNode->nextSibling()) |
| 690 childNodes.append(childNode); |
| 691 |
| 692 for (NodeVector::const_iterator it = childNodes.begin(); it != childNodes.en
d(); it++) { |
| 693 Node* childNode = it->get(); |
686 if (childNode->isTextNode() || !isBlock(childNode) || childNode->hasTagN
ame(preTag)) { | 694 if (childNode->isTextNode() || !isBlock(childNode) || childNode->hasTagN
ame(preTag)) { |
687 // In this case, put a span tag around the child node. | 695 // In this case, put a span tag around the child node. |
688 RefPtr<Node> newNode = parentNode->cloneNode(false); | 696 RefPtr<Node> newNode = parentNode->cloneNode(false); |
689 ASSERT(newNode->hasTagName(spanTag)); | 697 ASSERT(newNode->hasTagName(spanTag)); |
690 HTMLElement* newSpan = static_cast<HTMLElement*>(newNode.get()); | 698 HTMLElement* newSpan = static_cast<HTMLElement*>(newNode.get()); |
691 setNodeAttribute(newSpan, styleAttr, parentStyle->cssText()); | 699 setNodeAttribute(newSpan, styleAttr, parentStyle->cssText()); |
692 insertNodeAfter(newSpan, childNode); | 700 insertNodeAfter(newSpan, childNode); |
693 ExceptionCode ec = 0; | 701 ExceptionCode ec = 0; |
694 newSpan->appendChild(childNode, ec); | 702 newSpan->appendChild(childNode, ec); |
695 ASSERT(!ec); | 703 ASSERT(!ec); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 // This will leave a br between the split. | 865 // This will leave a br between the split. |
858 Node* br = endingSelection().start().node(); | 866 Node* br = endingSelection().start().node(); |
859 ASSERT(br->hasTagName(brTag)); | 867 ASSERT(br->hasTagName(brTag)); |
860 // Insert content between the two blockquotes, but remove the br (since
it was just a placeholder). | 868 // Insert content between the two blockquotes, but remove the br (since
it was just a placeholder). |
861 insertionPos = positionInParentBeforeNode(br); | 869 insertionPos = positionInParentBeforeNode(br); |
862 removeNode(br); | 870 removeNode(br); |
863 } | 871 } |
864 | 872 |
865 // Inserting content could cause whitespace to collapse, e.g. inserting <div
>foo</div> into hello^ world. | 873 // Inserting content could cause whitespace to collapse, e.g. inserting <div
>foo</div> into hello^ world. |
866 prepareWhitespaceAtPositionForSplit(insertionPos); | 874 prepareWhitespaceAtPositionForSplit(insertionPos); |
| 875 |
| 876 // If the downstream node has been removed there's no point in continuing. |
| 877 if (!insertionPos.downstream().node()) |
| 878 return; |
867 | 879 |
868 // NOTE: This would be an incorrect usage of downstream() if downstream() we
re changed to mean the last position after | 880 // NOTE: This would be an incorrect usage of downstream() if downstream() we
re changed to mean the last position after |
869 // 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 | 881 // 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 |
870 // away, there are positions after the br which map to the same visible posi
tion as [br, 0]). | 882 // away, there are positions after the br which map to the same visible posi
tion as [br, 0]). |
871 Node* endBR = insertionPos.downstream().node()->hasTagName(brTag) ? insertio
nPos.downstream().node() : 0; | 883 Node* endBR = insertionPos.downstream().node()->hasTagName(brTag) ? insertio
nPos.downstream().node() : 0; |
872 VisiblePosition originalVisPosBeforeEndBR; | 884 VisiblePosition originalVisPosBeforeEndBR; |
873 if (endBR) | 885 if (endBR) |
874 originalVisPosBeforeEndBR = VisiblePosition(endBR, 0, DOWNSTREAM).previo
us(); | 886 originalVisPosBeforeEndBR = VisiblePosition(endBR, 0, DOWNSTREAM).previo
us(); |
875 | 887 |
876 startBlock = enclosingBlock(insertionPos.node()); | 888 startBlock = enclosingBlock(insertionPos.node()); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 else | 947 else |
936 insertNodeAtAndUpdateNodesInserted(refNode, insertionPos); | 948 insertNodeAtAndUpdateNodesInserted(refNode, insertionPos); |
937 | 949 |
938 // Mutation events (bug 22634) may have already removed the inserted content | 950 // Mutation events (bug 22634) may have already removed the inserted content |
939 if (!refNode->inDocument()) | 951 if (!refNode->inDocument()) |
940 return; | 952 return; |
941 | 953 |
942 bool plainTextFragment = isPlainTextMarkup(refNode.get()); | 954 bool plainTextFragment = isPlainTextMarkup(refNode.get()); |
943 | 955 |
944 while (node) { | 956 while (node) { |
945 Node* next = node->nextSibling(); | 957 RefPtr<Node> next = node->nextSibling(); |
946 fragment.removeNode(node); | 958 fragment.removeNode(node.get()); |
947 insertNodeAfterAndUpdateNodesInserted(node, refNode.get()); | 959 insertNodeAfterAndUpdateNodesInserted(node, refNode.get()); |
948 | 960 |
949 // Mutation events (bug 22634) may have already removed the inserted con
tent | 961 // Mutation events (bug 22634) may have already removed the inserted con
tent |
950 if (!node->inDocument()) | 962 if (!node->inDocument()) |
951 return; | 963 return; |
952 | 964 |
953 refNode = node; | 965 refNode = node; |
954 if (node && plainTextFragment) | 966 if (node && plainTextFragment) |
955 plainTextFragment = isPlainTextMarkup(node.get()); | 967 plainTextFragment = isPlainTextMarkup(node.get()); |
956 node = next; | 968 node = next; |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 end = Position(start.anchorNode(), start.offsetInContainerNode() + text.leng
th()); | 1280 end = Position(start.anchorNode(), start.offsetInContainerNode() + text.leng
th()); |
1269 | 1281 |
1270 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en
d); | 1282 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en
d); |
1271 | 1283 |
1272 setEndingSelection(selectionAfterReplace); | 1284 setEndingSelection(selectionAfterReplace); |
1273 | 1285 |
1274 return true; | 1286 return true; |
1275 } | 1287 } |
1276 | 1288 |
1277 } // namespace WebCore | 1289 } // namespace WebCore |
OLD | NEW |