| 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 |