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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 } | 141 } |
142 | 142 |
143 ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
ragment, const VisibleSelection& selection) | 143 ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
ragment, const VisibleSelection& selection) |
144 : m_document(document), | 144 : m_document(document), |
145 m_fragment(fragment), | 145 m_fragment(fragment), |
146 m_hasInterchangeNewlineAtStart(false), | 146 m_hasInterchangeNewlineAtStart(false), |
147 m_hasInterchangeNewlineAtEnd(false) | 147 m_hasInterchangeNewlineAtEnd(false) |
148 { | 148 { |
149 if (!m_document) | 149 if (!m_document) |
150 return; | 150 return; |
151 if (!m_fragment) | 151 if (!m_fragment || !m_fragment->hasChildren()) |
152 return; | |
153 if (!m_fragment->firstChild()) | |
154 return; | 152 return; |
155 | 153 |
156 RefPtrWillBeRawPtr<Element> editableRoot = selection.rootEditableElement(); | 154 RefPtrWillBeRawPtr<Element> editableRoot = selection.rootEditableElement(); |
157 ASSERT(editableRoot); | 155 ASSERT(editableRoot); |
158 if (!editableRoot) | 156 if (!editableRoot) |
159 return; | 157 return; |
160 | 158 |
161 Node* shadowAncestorNode; | 159 Node* shadowAncestorNode; |
162 if (editableRoot->isInShadowTree()) | 160 if (editableRoot->isInShadowTree()) |
163 shadowAncestorNode = editableRoot->shadowHost(); | 161 shadowAncestorNode = editableRoot->shadowHost(); |
(...skipping 21 matching lines...) Expand all Loading... |
185 removeUnrenderedNodes(holder.get()); | 183 removeUnrenderedNodes(holder.get()); |
186 restoreAndRemoveTestRenderingNodesToFragment(holder.get()); | 184 restoreAndRemoveTestRenderingNodesToFragment(holder.get()); |
187 | 185 |
188 // Give the root a chance to change the text. | 186 // Give the root a chance to change the text. |
189 RefPtrWillBeRawPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::c
reate(text); | 187 RefPtrWillBeRawPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::c
reate(text); |
190 editableRoot->dispatchEvent(evt, ASSERT_NO_EXCEPTION); | 188 editableRoot->dispatchEvent(evt, ASSERT_NO_EXCEPTION); |
191 if (text != evt->text() || !editableRoot->rendererIsRichlyEditable()) { | 189 if (text != evt->text() || !editableRoot->rendererIsRichlyEditable()) { |
192 restoreAndRemoveTestRenderingNodesToFragment(holder.get()); | 190 restoreAndRemoveTestRenderingNodesToFragment(holder.get()); |
193 | 191 |
194 m_fragment = createFragmentFromText(selection.toNormalizedRange().get(),
evt->text()); | 192 m_fragment = createFragmentFromText(selection.toNormalizedRange().get(),
evt->text()); |
195 if (!m_fragment->firstChild()) | 193 if (!m_fragment->hasChildren()) |
196 return; | 194 return; |
197 | 195 |
198 holder = insertFragmentForTestRendering(editableRoot.get()); | 196 holder = insertFragmentForTestRendering(editableRoot.get()); |
199 removeInterchangeNodes(holder.get()); | 197 removeInterchangeNodes(holder.get()); |
200 removeUnrenderedNodes(holder.get()); | 198 removeUnrenderedNodes(holder.get()); |
201 restoreAndRemoveTestRenderingNodesToFragment(holder.get()); | 199 restoreAndRemoveTestRenderingNodesToFragment(holder.get()); |
202 } | 200 } |
203 } | 201 } |
204 | 202 |
205 bool ReplacementFragment::isEmpty() const | 203 bool ReplacementFragment::isEmpty() const |
206 { | 204 { |
207 return (!m_fragment || !m_fragment->firstChild()) && !m_hasInterchangeNewlin
eAtStart && !m_hasInterchangeNewlineAtEnd; | 205 return (!m_fragment || !m_fragment->hasChildren()) && !m_hasInterchangeNewli
neAtStart && !m_hasInterchangeNewlineAtEnd; |
208 } | 206 } |
209 | 207 |
210 Node *ReplacementFragment::firstChild() const | 208 Node *ReplacementFragment::firstChild() const |
211 { | 209 { |
212 return m_fragment ? m_fragment->firstChild() : 0; | 210 return m_fragment ? m_fragment->firstChild() : 0; |
213 } | 211 } |
214 | 212 |
215 Node *ReplacementFragment::lastChild() const | 213 Node *ReplacementFragment::lastChild() const |
216 { | 214 { |
217 return m_fragment ? m_fragment->lastChild() : 0; | 215 return m_fragment ? m_fragment->lastChild() : 0; |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 removeNodePreservingChildren(element); | 539 removeNodePreservingChildren(element); |
542 continue; | 540 continue; |
543 } | 541 } |
544 | 542 |
545 if (element->parentNode() && element->parentNode()->rendererIsRichlyEdit
able()) | 543 if (element->parentNode() && element->parentNode()->rendererIsRichlyEdit
able()) |
546 removeNodeAttribute(element, contenteditableAttr); | 544 removeNodeAttribute(element, contenteditableAttr); |
547 | 545 |
548 // WebKit used to not add display: inline and float: none on copy. | 546 // WebKit used to not add display: inline and float: none on copy. |
549 // Keep this code around for backward compatibility | 547 // Keep this code around for backward compatibility |
550 if (isLegacyAppleStyleSpan(element)) { | 548 if (isLegacyAppleStyleSpan(element)) { |
551 if (!element->firstChild()) { | 549 if (!element->hasChildren()) { |
552 insertedNodes.willRemoveNodePreservingChildren(*element); | 550 insertedNodes.willRemoveNodePreservingChildren(*element); |
553 removeNodePreservingChildren(element); | 551 removeNodePreservingChildren(element); |
554 continue; | 552 continue; |
555 } | 553 } |
556 // There are other styles that style rules can give to style spans, | 554 // There are other styles that style rules can give to style spans, |
557 // but these are the two important ones because they'll prevent | 555 // but these are the two important ones because they'll prevent |
558 // inserted content from appearing in the right paragraph. | 556 // inserted content from appearing in the right paragraph. |
559 // FIXME: Hyatt is concerned that selectively using display:inline w
ill give inconsistent | 557 // FIXME: Hyatt is concerned that selectively using display:inline w
ill give inconsistent |
560 // results. We already know one issue because td elements ignore the
ir display property | 558 // results. We already know one issue because td elements ignore the
ir display property |
561 // in quirks mode (which Mail.app is always in). We should look for
an alternative. | 559 // in quirks mode (which Mail.app is always in). We should look for
an alternative. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 removeNode(node); | 660 removeNode(node); |
663 if (ancestor->nextSibling()) | 661 if (ancestor->nextSibling()) |
664 insertNodeBefore(node, ancestor->nextSibling()); | 662 insertNodeBefore(node, ancestor->nextSibling()); |
665 else | 663 else |
666 appendNode(node, ancestor->parentNode()); | 664 appendNode(node, ancestor->parentNode()); |
667 } else { | 665 } else { |
668 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(node.get(), anc
estor.get(), true); | 666 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(node.get(), anc
estor.get(), true); |
669 removeNode(node); | 667 removeNode(node); |
670 insertNodeBefore(node, nodeToSplitTo); | 668 insertNodeBefore(node, nodeToSplitTo); |
671 } | 669 } |
672 if (!ancestor->firstChild()) | 670 if (!ancestor->hasChildren()) |
673 removeNode(ancestor.release()); | 671 removeNode(ancestor.release()); |
674 } | 672 } |
675 | 673 |
676 static inline bool nodeHasVisibleRenderText(Text& text) | 674 static inline bool nodeHasVisibleRenderText(Text& text) |
677 { | 675 { |
678 return text.renderer() && text.renderer()->renderedTextLength() > 0; | 676 return text.renderer() && text.renderer()->renderedTextLength() > 0; |
679 } | 677 } |
680 | 678 |
681 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins
ertedNodes) | 679 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins
ertedNodes) |
682 { | 680 { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 // This operation requires that only editing styles to be removed from sourc
eDocumentStyle. | 793 // This operation requires that only editing styles to be removed from sourc
eDocumentStyle. |
796 style->prepareToApplyAt(firstPositionInNode(context)); | 794 style->prepareToApplyAt(firstPositionInNode(context)); |
797 | 795 |
798 // Remove block properties in the span's style. This prevents properties tha
t probably have no effect | 796 // Remove block properties in the span's style. This prevents properties tha
t probably have no effect |
799 // currently from affecting blocks later if the style is cloned for a new bl
ock element during a future | 797 // currently from affecting blocks later if the style is cloned for a new bl
ock element during a future |
800 // editing operation. | 798 // editing operation. |
801 // FIXME: They *can* have an effect currently if blocks beneath the style sp
an aren't individually marked | 799 // FIXME: They *can* have an effect currently if blocks beneath the style sp
an aren't individually marked |
802 // with block styles by the editing engine used to style them. WebKit doesn
't do this, but others might. | 800 // with block styles by the editing engine used to style them. WebKit doesn
't do this, but others might. |
803 style->removeBlockProperties(); | 801 style->removeBlockProperties(); |
804 | 802 |
805 if (style->isEmpty() || !wrappingStyleSpan->firstChild()) { | 803 if (style->isEmpty() || !wrappingStyleSpan->hasChildren()) { |
806 insertedNodes.willRemoveNodePreservingChildren(*wrappingStyleSpan); | 804 insertedNodes.willRemoveNodePreservingChildren(*wrappingStyleSpan); |
807 removeNodePreservingChildren(wrappingStyleSpan); | 805 removeNodePreservingChildren(wrappingStyleSpan); |
808 } else { | 806 } else { |
809 setNodeAttribute(wrappingStyleSpan, styleAttr, AtomicString(style->style
()->asText())); | 807 setNodeAttribute(wrappingStyleSpan, styleAttr, AtomicString(style->style
()->asText())); |
810 } | 808 } |
811 } | 809 } |
812 | 810 |
813 void ReplaceSelectionCommand::mergeEndIfNeeded() | 811 void ReplaceSelectionCommand::mergeEndIfNeeded() |
814 { | 812 { |
815 if (!m_shouldMergeEnd) | 813 if (!m_shouldMergeEnd) |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1530 void ReplaceSelectionCommand::trace(Visitor* visitor) | 1528 void ReplaceSelectionCommand::trace(Visitor* visitor) |
1531 { | 1529 { |
1532 visitor->trace(m_startOfInsertedContent); | 1530 visitor->trace(m_startOfInsertedContent); |
1533 visitor->trace(m_endOfInsertedContent); | 1531 visitor->trace(m_endOfInsertedContent); |
1534 visitor->trace(m_insertionStyle); | 1532 visitor->trace(m_insertionStyle); |
1535 visitor->trace(m_documentFragment); | 1533 visitor->trace(m_documentFragment); |
1536 CompositeEditCommand::trace(visitor); | 1534 CompositeEditCommand::trace(visitor); |
1537 } | 1535 } |
1538 | 1536 |
1539 } // namespace blink | 1537 } // namespace blink |
OLD | NEW |