Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Side by Side Diff: third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp

Issue 1686483002: Oilpan: Remove most WillBe types from the code base (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 ReplacementFragment(Document*, DocumentFragment*, const VisibleSelection&); 76 ReplacementFragment(Document*, DocumentFragment*, const VisibleSelection&);
77 77
78 Node* firstChild() const; 78 Node* firstChild() const;
79 Node* lastChild() const; 79 Node* lastChild() const;
80 80
81 bool isEmpty() const; 81 bool isEmpty() const;
82 82
83 bool hasInterchangeNewlineAtStart() const { return m_hasInterchangeNewlineAt Start; } 83 bool hasInterchangeNewlineAtStart() const { return m_hasInterchangeNewlineAt Start; }
84 bool hasInterchangeNewlineAtEnd() const { return m_hasInterchangeNewlineAtEn d; } 84 bool hasInterchangeNewlineAtEnd() const { return m_hasInterchangeNewlineAtEn d; }
85 85
86 void removeNode(PassRefPtrWillBeRawPtr<Node>); 86 void removeNode(RawPtr<Node>);
87 void removeNodePreservingChildren(PassRefPtrWillBeRawPtr<ContainerNode>); 87 void removeNodePreservingChildren(RawPtr<ContainerNode>);
88 88
89 private: 89 private:
90 PassRefPtrWillBeRawPtr<HTMLElement> insertFragmentForTestRendering(Element* rootEditableElement); 90 RawPtr<HTMLElement> insertFragmentForTestRendering(Element* rootEditableElem ent);
91 void removeUnrenderedNodes(ContainerNode*); 91 void removeUnrenderedNodes(ContainerNode*);
92 void restoreAndRemoveTestRenderingNodesToFragment(Element*); 92 void restoreAndRemoveTestRenderingNodesToFragment(Element*);
93 void removeInterchangeNodes(ContainerNode*); 93 void removeInterchangeNodes(ContainerNode*);
94 94
95 void insertNodeBefore(PassRefPtrWillBeRawPtr<Node>, Node* refNode); 95 void insertNodeBefore(RawPtr<Node>, Node* refNode);
96 96
97 RefPtrWillBeMember<Document> m_document; 97 Member<Document> m_document;
98 RefPtrWillBeMember<DocumentFragment> m_fragment; 98 Member<DocumentFragment> m_fragment;
99 bool m_hasInterchangeNewlineAtStart; 99 bool m_hasInterchangeNewlineAtStart;
100 bool m_hasInterchangeNewlineAtEnd; 100 bool m_hasInterchangeNewlineAtEnd;
101 }; 101 };
102 102
103 static bool isInterchangeHTMLBRElement(const Node* node) 103 static bool isInterchangeHTMLBRElement(const Node* node)
104 { 104 {
105 DEFINE_STATIC_LOCAL(String, interchangeNewlineClassString, (AppleInterchange Newline)); 105 DEFINE_STATIC_LOCAL(String, interchangeNewlineClassString, (AppleInterchange Newline));
106 if (!isHTMLBRElement(node) || toHTMLBRElement(node)->getAttribute(classAttr) != interchangeNewlineClassString) 106 if (!isHTMLBRElement(node) || toHTMLBRElement(node)->getAttribute(classAttr) != interchangeNewlineClassString)
107 return false; 107 return false;
108 UseCounter::count(node->document(), UseCounter::EditingAppleInterchangeNewli ne); 108 UseCounter::count(node->document(), UseCounter::EditingAppleInterchangeNewli ne);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 : m_document(document) 148 : m_document(document)
149 , m_fragment(fragment) 149 , m_fragment(fragment)
150 , m_hasInterchangeNewlineAtStart(false) 150 , m_hasInterchangeNewlineAtStart(false)
151 , m_hasInterchangeNewlineAtEnd(false) 151 , m_hasInterchangeNewlineAtEnd(false)
152 { 152 {
153 if (!m_document) 153 if (!m_document)
154 return; 154 return;
155 if (!m_fragment || !m_fragment->hasChildren()) 155 if (!m_fragment || !m_fragment->hasChildren())
156 return; 156 return;
157 157
158 RefPtrWillBeRawPtr<Element> editableRoot = selection.rootEditableElement(); 158 RawPtr<Element> editableRoot = selection.rootEditableElement();
159 ASSERT(editableRoot); 159 ASSERT(editableRoot);
160 if (!editableRoot) 160 if (!editableRoot)
161 return; 161 return;
162 162
163 Element* shadowAncestorElement; 163 Element* shadowAncestorElement;
164 if (editableRoot->isInShadowTree()) 164 if (editableRoot->isInShadowTree())
165 shadowAncestorElement = editableRoot->shadowHost(); 165 shadowAncestorElement = editableRoot->shadowHost();
166 else 166 else
167 shadowAncestorElement = editableRoot.get(); 167 shadowAncestorElement = editableRoot.get();
168 168
169 if (!editableRoot->getAttributeEventListener(EventTypeNames::webkitBeforeTex tInserted) 169 if (!editableRoot->getAttributeEventListener(EventTypeNames::webkitBeforeTex tInserted)
170 // FIXME: Remove these checks once textareas and textfields actually reg ister an event handler. 170 // FIXME: Remove these checks once textareas and textfields actually reg ister an event handler.
171 && !(shadowAncestorElement && shadowAncestorElement->layoutObject() && s hadowAncestorElement->layoutObject()->isTextControl()) 171 && !(shadowAncestorElement && shadowAncestorElement->layoutObject() && s hadowAncestorElement->layoutObject()->isTextControl())
172 && editableRoot->layoutObjectIsRichlyEditable()) { 172 && editableRoot->layoutObjectIsRichlyEditable()) {
173 removeInterchangeNodes(m_fragment.get()); 173 removeInterchangeNodes(m_fragment.get());
174 return; 174 return;
175 } 175 }
176 176
177 RefPtrWillBeRawPtr<HTMLElement> holder = insertFragmentForTestRendering(edit ableRoot.get()); 177 RawPtr<HTMLElement> holder = insertFragmentForTestRendering(editableRoot.get ());
178 if (!holder) { 178 if (!holder) {
179 removeInterchangeNodes(m_fragment.get()); 179 removeInterchangeNodes(m_fragment.get());
180 return; 180 return;
181 } 181 }
182 182
183 const EphemeralRange range = VisibleSelection::selectionFromContentsOfNode(h older.get()).toNormalizedEphemeralRange(); 183 const EphemeralRange range = VisibleSelection::selectionFromContentsOfNode(h older.get()).toNormalizedEphemeralRange();
184 String text = plainText(range, static_cast<TextIteratorBehavior>(TextIterato rEmitsOriginalText | TextIteratorIgnoresStyleVisibility)); 184 String text = plainText(range, static_cast<TextIteratorBehavior>(TextIterato rEmitsOriginalText | TextIteratorIgnoresStyleVisibility));
185 185
186 removeInterchangeNodes(holder.get()); 186 removeInterchangeNodes(holder.get());
187 removeUnrenderedNodes(holder.get()); 187 removeUnrenderedNodes(holder.get());
188 restoreAndRemoveTestRenderingNodesToFragment(holder.get()); 188 restoreAndRemoveTestRenderingNodesToFragment(holder.get());
189 189
190 // Give the root a chance to change the text. 190 // Give the root a chance to change the text.
191 RefPtrWillBeRawPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::c reate(text); 191 RawPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text);
192 editableRoot->dispatchEvent(evt); 192 editableRoot->dispatchEvent(evt);
193 if (text != evt->text() || !editableRoot->layoutObjectIsRichlyEditable()) { 193 if (text != evt->text() || !editableRoot->layoutObjectIsRichlyEditable()) {
194 restoreAndRemoveTestRenderingNodesToFragment(holder.get()); 194 restoreAndRemoveTestRenderingNodesToFragment(holder.get());
195 195
196 m_fragment = createFragmentFromText(selection.toNormalizedEphemeralRange (), evt->text()); 196 m_fragment = createFragmentFromText(selection.toNormalizedEphemeralRange (), evt->text());
197 if (!m_fragment->hasChildren()) 197 if (!m_fragment->hasChildren())
198 return; 198 return;
199 199
200 holder = insertFragmentForTestRendering(editableRoot.get()); 200 holder = insertFragmentForTestRendering(editableRoot.get());
201 removeInterchangeNodes(holder.get()); 201 removeInterchangeNodes(holder.get());
(...skipping 10 matching lines...) Expand all
212 Node* ReplacementFragment::firstChild() const 212 Node* ReplacementFragment::firstChild() const
213 { 213 {
214 return m_fragment ? m_fragment->firstChild() : 0; 214 return m_fragment ? m_fragment->firstChild() : 0;
215 } 215 }
216 216
217 Node* ReplacementFragment::lastChild() const 217 Node* ReplacementFragment::lastChild() const
218 { 218 {
219 return m_fragment ? m_fragment->lastChild() : 0; 219 return m_fragment ? m_fragment->lastChild() : 0;
220 } 220 }
221 221
222 void ReplacementFragment::removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Co ntainerNode> node) 222 void ReplacementFragment::removeNodePreservingChildren(RawPtr<ContainerNode> nod e)
223 { 223 {
224 if (!node) 224 if (!node)
225 return; 225 return;
226 226
227 while (RefPtrWillBeRawPtr<Node> n = node->firstChild()) { 227 while (RawPtr<Node> n = node->firstChild()) {
228 removeNode(n); 228 removeNode(n);
229 insertNodeBefore(n.release(), node.get()); 229 insertNodeBefore(n.release(), node.get());
230 } 230 }
231 removeNode(node); 231 removeNode(node);
232 } 232 }
233 233
234 void ReplacementFragment::removeNode(PassRefPtrWillBeRawPtr<Node> node) 234 void ReplacementFragment::removeNode(RawPtr<Node> node)
235 { 235 {
236 if (!node) 236 if (!node)
237 return; 237 return;
238 238
239 ContainerNode* parent = node->nonShadowBoundaryParentNode(); 239 ContainerNode* parent = node->nonShadowBoundaryParentNode();
240 if (!parent) 240 if (!parent)
241 return; 241 return;
242 242
243 parent->removeChild(node.get()); 243 parent->removeChild(node.get());
244 } 244 }
245 245
246 void ReplacementFragment::insertNodeBefore(PassRefPtrWillBeRawPtr<Node> node, No de* refNode) 246 void ReplacementFragment::insertNodeBefore(RawPtr<Node> node, Node* refNode)
247 { 247 {
248 if (!node || !refNode) 248 if (!node || !refNode)
249 return; 249 return;
250 250
251 ContainerNode* parent = refNode->nonShadowBoundaryParentNode(); 251 ContainerNode* parent = refNode->nonShadowBoundaryParentNode();
252 if (!parent) 252 if (!parent)
253 return; 253 return;
254 254
255 parent->insertBefore(node, refNode); 255 parent->insertBefore(node, refNode);
256 } 256 }
257 257
258 PassRefPtrWillBeRawPtr<HTMLElement> ReplacementFragment::insertFragmentForTestRe ndering(Element* rootEditableElement) 258 RawPtr<HTMLElement> ReplacementFragment::insertFragmentForTestRendering(Element* rootEditableElement)
259 { 259 {
260 ASSERT(m_document); 260 ASSERT(m_document);
261 RefPtrWillBeRawPtr<HTMLElement> holder = createDefaultParagraphElement(*m_do cument.get()); 261 RawPtr<HTMLElement> holder = createDefaultParagraphElement(*m_document.get() );
262 262
263 holder->appendChild(m_fragment); 263 holder->appendChild(m_fragment);
264 rootEditableElement->appendChild(holder.get()); 264 rootEditableElement->appendChild(holder.get());
265 m_document->updateLayoutIgnorePendingStylesheets(); 265 m_document->updateLayoutIgnorePendingStylesheets();
266 266
267 return holder.release(); 267 return holder.release();
268 } 268 }
269 269
270 void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element* holder) 270 void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element* holder)
271 { 271 {
272 if (!holder) 272 if (!holder)
273 return; 273 return;
274 274
275 while (RefPtrWillBeRawPtr<Node> node = holder->firstChild()) { 275 while (RawPtr<Node> node = holder->firstChild()) {
276 holder->removeChild(node.get()); 276 holder->removeChild(node.get());
277 m_fragment->appendChild(node.get()); 277 m_fragment->appendChild(node.get());
278 } 278 }
279 279
280 removeNode(holder); 280 removeNode(holder);
281 } 281 }
282 282
283 void ReplacementFragment::removeUnrenderedNodes(ContainerNode* holder) 283 void ReplacementFragment::removeUnrenderedNodes(ContainerNode* holder)
284 { 284 {
285 WillBeHeapVector<RefPtrWillBeMember<Node>> unrendered; 285 HeapVector<Member<Node>> unrendered;
286 286
287 for (Node& node : NodeTraversal::descendantsOf(*holder)) { 287 for (Node& node : NodeTraversal::descendantsOf(*holder)) {
288 if (!isNodeRendered(node) && !isTableStructureNode(&node)) 288 if (!isNodeRendered(node) && !isTableStructureNode(&node))
289 unrendered.append(&node); 289 unrendered.append(&node);
290 } 290 }
291 291
292 for (auto& node : unrendered) 292 for (auto& node : unrendered)
293 removeNode(node); 293 removeNode(node);
294 } 294 }
295 295
(...skipping 22 matching lines...) Expand all
318 if (isInterchangeHTMLBRElement(node)) { 318 if (isInterchangeHTMLBRElement(node)) {
319 m_hasInterchangeNewlineAtEnd = true; 319 m_hasInterchangeNewlineAtEnd = true;
320 removeNode(node); 320 removeNode(node);
321 break; 321 break;
322 } 322 }
323 node = node->lastChild(); 323 node = node->lastChild();
324 } 324 }
325 325
326 node = container->firstChild(); 326 node = container->firstChild();
327 while (node) { 327 while (node) {
328 RefPtrWillBeRawPtr<Node> next = NodeTraversal::next(*node); 328 RawPtr<Node> next = NodeTraversal::next(*node);
329 if (isHTMLInterchangeConvertedSpaceSpan(node)) { 329 if (isHTMLInterchangeConvertedSpaceSpan(node)) {
330 HTMLElement& element = toHTMLElement(*node); 330 HTMLElement& element = toHTMLElement(*node);
331 next = NodeTraversal::nextSkippingChildren(element); 331 next = NodeTraversal::nextSkippingChildren(element);
332 removeNodePreservingChildren(&element); 332 removeNodePreservingChildren(&element);
333 } 333 }
334 node = next.get(); 334 node = next.get();
335 } 335 }
336 } 336 }
337 337
338 inline void ReplaceSelectionCommand::InsertedNodes::respondToNodeInsertion(Node& node) 338 inline void ReplaceSelectionCommand::InsertedNodes::respondToNodeInsertion(Node& node)
(...skipping 25 matching lines...) Expand all
364 } 364 }
365 365
366 inline void ReplaceSelectionCommand::InsertedNodes::didReplaceNode(Node& node, N ode& newNode) 366 inline void ReplaceSelectionCommand::InsertedNodes::didReplaceNode(Node& node, N ode& newNode)
367 { 367 {
368 if (m_firstNodeInserted.get() == node) 368 if (m_firstNodeInserted.get() == node)
369 m_firstNodeInserted = &newNode; 369 m_firstNodeInserted = &newNode;
370 if (m_lastNodeInserted.get() == node) 370 if (m_lastNodeInserted.get() == node)
371 m_lastNodeInserted = &newNode; 371 m_lastNodeInserted = &newNode;
372 } 372 }
373 373
374 ReplaceSelectionCommand::ReplaceSelectionCommand(Document& document, PassRefPtrW illBeRawPtr<DocumentFragment> fragment, CommandOptions options, EditAction editA ction) 374 ReplaceSelectionCommand::ReplaceSelectionCommand(Document& document, RawPtr<Docu mentFragment> fragment, CommandOptions options, EditAction editAction)
375 : CompositeEditCommand(document) 375 : CompositeEditCommand(document)
376 , m_selectReplacement(options & SelectReplacement) 376 , m_selectReplacement(options & SelectReplacement)
377 , m_smartReplace(options & SmartReplace) 377 , m_smartReplace(options & SmartReplace)
378 , m_matchStyle(options & MatchStyle) 378 , m_matchStyle(options & MatchStyle)
379 , m_documentFragment(fragment) 379 , m_documentFragment(fragment)
380 , m_preventNesting(options & PreventNesting) 380 , m_preventNesting(options & PreventNesting)
381 , m_movingParagraph(options & MovingParagraph) 381 , m_movingParagraph(options & MovingParagraph)
382 , m_editAction(editAction) 382 , m_editAction(editAction)
383 , m_sanitizeFragment(options & SanitizeFragment) 383 , m_sanitizeFragment(options & SanitizeFragment)
384 , m_shouldMergeEnd(false) 384 , m_shouldMergeEnd(false)
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 && (!isHTMLHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, de stinationBlock)) 477 && (!isHTMLHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, de stinationBlock))
478 // Don't merge to or from a position before or after a block because it would 478 // Don't merge to or from a position before or after a block because it would
479 // be a no-op and cause infinite recursion. 479 // be a no-op and cause infinite recursion.
480 && !isEnclosingBlock(sourceNode) && !isEnclosingBlock(destinationNode); 480 && !isEnclosingBlock(sourceNode) && !isEnclosingBlock(destinationNode);
481 } 481 }
482 482
483 // Style rules that match just inserted elements could change their appearance, like 483 // Style rules that match just inserted elements could change their appearance, like
484 // a div inserted into a document with div { display:inline; }. 484 // a div inserted into a document with div { display:inline; }.
485 void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert edNodes& insertedNodes) 485 void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert edNodes& insertedNodes)
486 { 486 {
487 RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf(); 487 RawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
488 RefPtrWillBeRawPtr<Node> next = nullptr; 488 RawPtr<Node> next = nullptr;
489 for (RefPtrWillBeRawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) { 489 for (RawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) {
490 // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance 490 // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance
491 491
492 next = NodeTraversal::next(*node); 492 next = NodeTraversal::next(*node);
493 if (!node->isStyledElement()) 493 if (!node->isStyledElement())
494 continue; 494 continue;
495 495
496 Element* element = toElement(node); 496 Element* element = toElement(node);
497 497
498 const StylePropertySet* inlineStyle = element->inlineStyle(); 498 const StylePropertySet* inlineStyle = element->inlineStyle();
499 RefPtrWillBeRawPtr<EditingStyle> newInlineStyle = EditingStyle::create(i nlineStyle); 499 RawPtr<EditingStyle> newInlineStyle = EditingStyle::create(inlineStyle);
500 if (inlineStyle) { 500 if (inlineStyle) {
501 if (element->isHTMLElement()) { 501 if (element->isHTMLElement()) {
502 Vector<QualifiedName> attributes; 502 Vector<QualifiedName> attributes;
503 HTMLElement* htmlElement = toHTMLElement(element); 503 HTMLElement* htmlElement = toHTMLElement(element);
504 ASSERT(htmlElement); 504 ASSERT(htmlElement);
505 505
506 if (newInlineStyle->conflictsWithImplicitStyleOfElement(htmlElem ent)) { 506 if (newInlineStyle->conflictsWithImplicitStyleOfElement(htmlElem ent)) {
507 // e.g. <b style="font-weight: normal;"> is converted to <sp an style="font-weight: normal;"> 507 // e.g. <b style="font-weight: normal;"> is converted to <sp an style="font-weight: normal;">
508 element = replaceElementWithSpanPreservingChildrenAndAttribu tes(htmlElement); 508 element = replaceElementWithSpanPreservingChildrenAndAttribu tes(htmlElement);
509 inlineStyle = element->inlineStyle(); 509 inlineStyle = element->inlineStyle();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 elements.add(theadTag.localName()); 628 elements.add(theadTag.localName());
629 elements.add(trTag.localName()); 629 elements.add(trTag.localName());
630 elements.add(ulTag.localName()); 630 elements.add(ulTag.localName());
631 elements.add(xmpTag.localName()); 631 elements.add(xmpTag.localName());
632 } 632 }
633 return elements.contains(name); 633 return elements.contains(name);
634 } 634 }
635 635
636 void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuild er(const InsertedNodes& insertedNodes) 636 void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuild er(const InsertedNodes& insertedNodes)
637 { 637 {
638 RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf(); 638 RawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
639 RefPtrWillBeRawPtr<Node> next = nullptr; 639 RawPtr<Node> next = nullptr;
640 for (RefPtrWillBeRawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) { 640 for (RawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) {
641 next = NodeTraversal::next(*node); 641 next = NodeTraversal::next(*node);
642 642
643 if (!node->isHTMLElement()) 643 if (!node->isHTMLElement())
644 continue; 644 continue;
645 // moveElementOutOfAncestor() in a previous iteration might have failed, 645 // moveElementOutOfAncestor() in a previous iteration might have failed,
646 // and |node| might have been detached from the document tree. 646 // and |node| might have been detached from the document tree.
647 if (!node->inDocument()) 647 if (!node->inDocument())
648 continue; 648 continue;
649 649
650 HTMLElement& element = toHTMLElement(*node); 650 HTMLElement& element = toHTMLElement(*node);
651 if (isProhibitedParagraphChild(element.localName())) { 651 if (isProhibitedParagraphChild(element.localName())) {
652 if (HTMLElement* paragraphElement = toHTMLElement(enclosingElementWi thTag(positionInParentBeforeNode(element), pTag))) 652 if (HTMLElement* paragraphElement = toHTMLElement(enclosingElementWi thTag(positionInParentBeforeNode(element), pTag)))
653 moveElementOutOfAncestor(&element, paragraphElement); 653 moveElementOutOfAncestor(&element, paragraphElement);
654 } 654 }
655 655
656 if (isHTMLHeaderElement(&element)) { 656 if (isHTMLHeaderElement(&element)) {
657 if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeO fType(positionInParentBeforeNode(element), isHTMLHeaderElement))) 657 if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeO fType(positionInParentBeforeNode(element), isHTMLHeaderElement)))
658 moveElementOutOfAncestor(&element, headerElement); 658 moveElementOutOfAncestor(&element, headerElement);
659 } 659 }
660 } 660 }
661 } 661 }
662 662
663 void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<El ement> prpElement, PassRefPtrWillBeRawPtr<Element> prpAncestor) 663 void ReplaceSelectionCommand::moveElementOutOfAncestor(RawPtr<Element> prpElemen t, RawPtr<Element> prpAncestor)
664 { 664 {
665 RefPtrWillBeRawPtr<Element> element = prpElement; 665 RawPtr<Element> element = prpElement;
666 RefPtrWillBeRawPtr<Element> ancestor = prpAncestor; 666 RawPtr<Element> ancestor = prpAncestor;
667 667
668 if (!ancestor->parentNode()->hasEditableStyle()) 668 if (!ancestor->parentNode()->hasEditableStyle())
669 return; 669 return;
670 670
671 VisiblePosition positionAtEndOfNode = createVisiblePosition(lastPositionInOr AfterNode(element.get())); 671 VisiblePosition positionAtEndOfNode = createVisiblePosition(lastPositionInOr AfterNode(element.get()));
672 VisiblePosition lastPositionInParagraph = createVisiblePosition(lastPosition InNode(ancestor.get())); 672 VisiblePosition lastPositionInParagraph = createVisiblePosition(lastPosition InNode(ancestor.get()));
673 if (positionAtEndOfNode.deepEquivalent() == lastPositionInParagraph.deepEqui valent()) { 673 if (positionAtEndOfNode.deepEquivalent() == lastPositionInParagraph.deepEqui valent()) {
674 removeNode(element); 674 removeNode(element);
675 if (ancestor->nextSibling()) 675 if (ancestor->nextSibling())
676 insertNodeBefore(element, ancestor->nextSibling()); 676 insertNodeBefore(element, ancestor->nextSibling());
677 else 677 else
678 appendNode(element, ancestor->parentNode()); 678 appendNode(element, ancestor->parentNode());
679 } else { 679 } else {
680 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(), ancestor.get(), true); 680 RawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(), ancestor.get (), true);
681 removeNode(element); 681 removeNode(element);
682 insertNodeBefore(element, nodeToSplitTo); 682 insertNodeBefore(element, nodeToSplitTo);
683 } 683 }
684 if (!ancestor->hasChildren()) 684 if (!ancestor->hasChildren())
685 removeNode(ancestor.release()); 685 removeNode(ancestor.release());
686 } 686 }
687 687
688 static inline bool nodeHasVisibleLayoutText(Text& text) 688 static inline bool nodeHasVisibleLayoutText(Text& text)
689 { 689 {
690 return text.layoutObject() && text.layoutObject()->resolvedTextLength() > 0; 690 return text.layoutObject() && text.layoutObject()->resolvedTextLength() > 0;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 // and doesn't receive the optimization. 750 // and doesn't receive the optimization.
751 if (isMailPasteAsQuotationHTMLBlockQuoteElement(topNode) || enclosingNodeOfT ype(firstPositionInOrBeforeNode(topNode), isMailHTMLBlockquoteElement, CanCrossE ditingBoundary)) 751 if (isMailPasteAsQuotationHTMLBlockQuoteElement(topNode) || enclosingNodeOfT ype(firstPositionInOrBeforeNode(topNode), isMailHTMLBlockquoteElement, CanCrossE ditingBoundary))
752 return false; 752 return false;
753 753
754 // Either there are no style spans in the fragment or a WebKit client has ad ded content to the fragment 754 // Either there are no style spans in the fragment or a WebKit client has ad ded content to the fragment
755 // before inserting it. Look for and handle style spans after insertion. 755 // before inserting it. Look for and handle style spans after insertion.
756 if (!isLegacyAppleHTMLSpanElement(topNode)) 756 if (!isLegacyAppleHTMLSpanElement(topNode))
757 return false; 757 return false;
758 758
759 HTMLSpanElement* wrappingStyleSpan = toHTMLSpanElement(topNode); 759 HTMLSpanElement* wrappingStyleSpan = toHTMLSpanElement(topNode);
760 RefPtrWillBeRawPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create( insertionPos.parentAnchoredEquivalent()); 760 RawPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create(insertionPos .parentAnchoredEquivalent());
761 String styleText = styleAtInsertionPos->style()->asText(); 761 String styleText = styleAtInsertionPos->style()->asText();
762 762
763 // FIXME: This string comparison is a naive way of comparing two styles. 763 // FIXME: This string comparison is a naive way of comparing two styles.
764 // We should be taking the diff and check that the diff is empty. 764 // We should be taking the diff and check that the diff is empty.
765 if (styleText != wrappingStyleSpan->getAttribute(styleAttr)) 765 if (styleText != wrappingStyleSpan->getAttribute(styleAttr))
766 return false; 766 return false;
767 767
768 fragment.removeNodePreservingChildren(wrappingStyleSpan); 768 fragment.removeNodePreservingChildren(wrappingStyleSpan);
769 return true; 769 return true;
770 } 770 }
(...skipping 18 matching lines...) Expand all
789 wrappingStyleSpan = toHTMLSpanElement(&node); 789 wrappingStyleSpan = toHTMLSpanElement(&node);
790 break; 790 break;
791 } 791 }
792 } 792 }
793 793
794 // There might not be any style spans if we're pasting from another applicat ion or if 794 // There might not be any style spans if we're pasting from another applicat ion or if
795 // we are here because of a document.execCommand("InsertHTML", ...) call. 795 // we are here because of a document.execCommand("InsertHTML", ...) call.
796 if (!wrappingStyleSpan) 796 if (!wrappingStyleSpan)
797 return; 797 return;
798 798
799 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(wrappingStyleS pan->inlineStyle()); 799 RawPtr<EditingStyle> style = EditingStyle::create(wrappingStyleSpan->inlineS tyle());
800 ContainerNode* context = wrappingStyleSpan->parentNode(); 800 ContainerNode* context = wrappingStyleSpan->parentNode();
801 801
802 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if yo u're pasting into a quoted region, 802 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if yo u're pasting into a quoted region,
803 // styles from blockquoteElement are allowed to override those from the sour ce document, see <rdar://problem/4930986> and <rdar://problem/5089327>. 803 // styles from blockquoteElement are allowed to override those from the sour ce document, see <rdar://problem/4930986> and <rdar://problem/5089327>.
804 HTMLQuoteElement* blockquoteElement = isMailPasteAsQuotationHTMLBlockQuoteEl ement(context) ? 804 HTMLQuoteElement* blockquoteElement = isMailPasteAsQuotationHTMLBlockQuoteEl ement(context) ?
805 toHTMLQuoteElement(context) : 805 toHTMLQuoteElement(context) :
806 toHTMLQuoteElement(enclosingNodeOfType(firstPositionInNode(context), isM ailHTMLBlockquoteElement, CanCrossEditingBoundary)); 806 toHTMLQuoteElement(enclosingNodeOfType(firstPositionInNode(context), isM ailHTMLBlockquoteElement, CanCrossEditingBoundary));
807 if (blockquoteElement) 807 if (blockquoteElement)
808 context = document().documentElement(); 808 context = document().documentElement();
809 809
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 // include the what was the start of the selection that was pasted into, so that we preserve that paragraph's 844 // include the what was the start of the selection that was pasted into, so that we preserve that paragraph's
845 // block styles. 845 // block styles.
846 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC ontent) && !isStartOfParagraph(startOfInsertedContent)); 846 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC ontent) && !isStartOfParagraph(startOfInsertedContent));
847 847
848 VisiblePosition destination = mergeForward ? nextPositionOf(endOfInsertedCon tent) : endOfInsertedContent; 848 VisiblePosition destination = mergeForward ? nextPositionOf(endOfInsertedCon tent) : endOfInsertedContent;
849 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end OfInsertedContent) : nextPositionOf(endOfInsertedContent); 849 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end OfInsertedContent) : nextPositionOf(endOfInsertedContent);
850 850
851 // Merging forward could result in deleting the destination anchor node. 851 // Merging forward could result in deleting the destination anchor node.
852 // To avoid this, we add a placeholder node before the start of the paragrap h. 852 // To avoid this, we add a placeholder node before the start of the paragrap h.
853 if (endOfParagraph(startOfParagraphToMove).deepEquivalent() == destination.d eepEquivalent()) { 853 if (endOfParagraph(startOfParagraphToMove).deepEquivalent() == destination.d eepEquivalent()) {
854 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = HTMLBRElement::create(do cument()); 854 RawPtr<HTMLBRElement> placeholder = HTMLBRElement::create(document());
855 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().an chorNode()); 855 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().an chorNode());
856 destination = createVisiblePosition(positionBeforeNode(placeholder.get() )); 856 destination = createVisiblePosition(positionBeforeNode(placeholder.get() ));
857 } 857 }
858 858
859 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove) , destination); 859 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove) , destination);
860 860
861 // Merging forward will remove m_endOfInsertedContent from the document. 861 // Merging forward will remove m_endOfInsertedContent from the document.
862 if (mergeForward) { 862 if (mergeForward) {
863 if (m_startOfInsertedContent.isOrphan()) 863 if (m_startOfInsertedContent.isOrphan())
864 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui valent(); 864 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui valent();
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return; 1024 return;
1025 1025
1026 // NOTE: This would be an incorrect usage of downstream() if downstream() we re changed to mean the last position after 1026 // NOTE: This would be an incorrect usage of downstream() if downstream() we re changed to mean the last position after
1027 // 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 1027 // 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
1028 // away, there are positions after the br which map to the same visible posi tion as [br, 0]). 1028 // away, there are positions after the br which map to the same visible posi tion as [br, 0]).
1029 HTMLBRElement* endBR = isHTMLBRElement(*mostForwardCaretPosition(insertionPo s).anchorNode()) ? toHTMLBRElement(mostForwardCaretPosition(insertionPos).anchor Node()) : 0; 1029 HTMLBRElement* endBR = isHTMLBRElement(*mostForwardCaretPosition(insertionPo s).anchorNode()) ? toHTMLBRElement(mostForwardCaretPosition(insertionPos).anchor Node()) : 0;
1030 VisiblePosition originalVisPosBeforeEndBR; 1030 VisiblePosition originalVisPosBeforeEndBR;
1031 if (endBR) 1031 if (endBR)
1032 originalVisPosBeforeEndBR = previousPositionOf(createVisiblePosition(pos itionBeforeNode(endBR))); 1032 originalVisPosBeforeEndBR = previousPositionOf(createVisiblePosition(pos itionBeforeNode(endBR)));
1033 1033
1034 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in sertionPos.anchorNode()); 1034 RawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(insertionPos.a nchorNode());
1035 1035
1036 // Adjust insertionPos to prevent nesting. 1036 // Adjust insertionPos to prevent nesting.
1037 // If the start was in a Mail blockquote, we will have already handled adjus ting insertionPos above. 1037 // If the start was in a Mail blockquote, we will have already handled adjus ting insertionPos above.
1038 if (m_preventNesting && enclosingBlockOfInsertionPos && !isTableCell(enclosi ngBlockOfInsertionPos.get()) && !startIsInsideMailBlockquote) { 1038 if (m_preventNesting && enclosingBlockOfInsertionPos && !isTableCell(enclosi ngBlockOfInsertionPos.get()) && !startIsInsideMailBlockquote) {
1039 ASSERT(enclosingBlockOfInsertionPos != currentRoot); 1039 ASSERT(enclosingBlockOfInsertionPos != currentRoot);
1040 VisiblePosition visibleInsertionPos = createVisiblePosition(insertionPos ); 1040 VisiblePosition visibleInsertionPos = createVisiblePosition(insertionPos );
1041 if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInserti onPos) && fragment.hasInterchangeNewlineAtEnd())) 1041 if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInserti onPos) && fragment.hasInterchangeNewlineAtEnd()))
1042 insertionPos = positionInParentAfterNode(*enclosingBlockOfInsertionP os); 1042 insertionPos = positionInParentAfterNode(*enclosingBlockOfInsertionP os);
1043 else if (isStartOfBlock(visibleInsertionPos)) 1043 else if (isStartOfBlock(visibleInsertionPos))
1044 insertionPos = positionInParentBeforeNode(*enclosingBlockOfInsertion Pos); 1044 insertionPos = positionInParentBeforeNode(*enclosingBlockOfInsertion Pos);
(...skipping 28 matching lines...) Expand all
1073 // This way we can produce a less verbose markup. 1073 // This way we can produce a less verbose markup.
1074 // We can skip this optimization for fragments not wrapped in one of 1074 // We can skip this optimization for fragments not wrapped in one of
1075 // our style spans and for positions inside list items 1075 // our style spans and for positions inside list items
1076 // since insertAsListItems already does the right thing. 1076 // since insertAsListItems already does the right thing.
1077 if (!m_matchStyle && !enclosingList(insertionPos.computeContainerNode())) { 1077 if (!m_matchStyle && !enclosingList(insertionPos.computeContainerNode())) {
1078 if (insertionPos.computeContainerNode()->isTextNode() && insertionPos.of fsetInContainerNode() && !insertionPos.atLastEditingPositionForNode()) { 1078 if (insertionPos.computeContainerNode()->isTextNode() && insertionPos.of fsetInContainerNode() && !insertionPos.atLastEditingPositionForNode()) {
1079 splitTextNode(toText(insertionPos.computeContainerNode()), insertion Pos.offsetInContainerNode()); 1079 splitTextNode(toText(insertionPos.computeContainerNode()), insertion Pos.offsetInContainerNode());
1080 insertionPos = firstPositionInNode(insertionPos.computeContainerNode ()); 1080 insertionPos = firstPositionInNode(insertionPos.computeContainerNode ());
1081 } 1081 }
1082 1082
1083 if (RefPtrWillBeRawPtr<HTMLElement> elementToSplitTo = elementToSplitToA voidPastingIntoInlineElementsWithStyle(insertionPos)) { 1083 if (RawPtr<HTMLElement> elementToSplitTo = elementToSplitToAvoidPastingI ntoInlineElementsWithStyle(insertionPos)) {
1084 if (insertionPos.computeContainerNode() != elementToSplitTo->parentN ode()) { 1084 if (insertionPos.computeContainerNode() != elementToSplitTo->parentN ode()) {
1085 Node* splitStart = insertionPos.computeNodeAfterPosition(); 1085 Node* splitStart = insertionPos.computeNodeAfterPosition();
1086 if (!splitStart) 1086 if (!splitStart)
1087 splitStart = insertionPos.computeContainerNode(); 1087 splitStart = insertionPos.computeContainerNode();
1088 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(splitSt art, elementToSplitTo->parentNode()).get(); 1088 RawPtr<Node> nodeToSplitTo = splitTreeToNode(splitStart, element ToSplitTo->parentNode()).get();
1089 insertionPos = positionInParentBeforeNode(*nodeToSplitTo); 1089 insertionPos = positionInParentBeforeNode(*nodeToSplitTo);
1090 } 1090 }
1091 } 1091 }
1092 } 1092 }
1093 1093
1094 // FIXME: When pasting rich content we're often prevented from heading down the fast path by style spans. Try 1094 // FIXME: When pasting rich content we're often prevented from heading down the fast path by style spans. Try
1095 // again here if they've been removed. 1095 // again here if they've been removed.
1096 1096
1097 // 1) Insert the content. 1097 // 1) Insert the content.
1098 // 2) Remove redundant styles and style tags, this inner <b> for example: <b >foo <b>bar</b> baz</b>. 1098 // 2) Remove redundant styles and style tags, this inner <b> for example: <b >foo <b>bar</b> baz</b>.
1099 // 3) Merge the start of the added content with the content before the posit ion being pasted into. 1099 // 3) Merge the start of the added content with the content before the posit ion being pasted into.
1100 // 4) Do one of the following: a) expand the last br if the fragment ends wi th one and it collapsed, 1100 // 4) Do one of the following: a) expand the last br if the fragment ends wi th one and it collapsed,
1101 // b) merge the last paragraph of the incoming fragment with the paragraph t hat contained the 1101 // b) merge the last paragraph of the incoming fragment with the paragraph t hat contained the
1102 // end of the selection that was pasted into, or c) handle an interchange ne wline at the end of the 1102 // end of the selection that was pasted into, or c) handle an interchange ne wline at the end of the
1103 // incoming fragment. 1103 // incoming fragment.
1104 // 5) Add spaces for smart replace. 1104 // 5) Add spaces for smart replace.
1105 // 6) Select the replacement if requested, and match style if requested. 1105 // 6) Select the replacement if requested, and match style if requested.
1106 1106
1107 InsertedNodes insertedNodes; 1107 InsertedNodes insertedNodes;
1108 RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild(); 1108 RawPtr<Node> refNode = fragment.firstChild();
1109 ASSERT(refNode); 1109 ASSERT(refNode);
1110 RefPtrWillBeRawPtr<Node> node = refNode->nextSibling(); 1110 RawPtr<Node> node = refNode->nextSibling();
1111 1111
1112 fragment.removeNode(refNode); 1112 fragment.removeNode(refNode);
1113 1113
1114 Element* blockStart = enclosingBlock(insertionPos.anchorNode()); 1114 Element* blockStart = enclosingBlock(insertionPos.anchorNode());
1115 if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNo de.get()) && isHTMLListElement(refNode->firstChild()))) 1115 if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNo de.get()) && isHTMLListElement(refNode->firstChild())))
1116 && blockStart && blockStart->layoutObject()->isListItem() && blockStart- >parentNode()->hasEditableStyle()) { 1116 && blockStart && blockStart->layoutObject()->isListItem() && blockStart- >parentNode()->hasEditableStyle()) {
1117 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio nPos, insertedNodes); 1117 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio nPos, insertedNodes);
1118 } else { 1118 } else {
1119 insertNodeAt(refNode, insertionPos); 1119 insertNodeAt(refNode, insertionPos);
1120 insertedNodes.respondToNodeInsertion(*refNode); 1120 insertedNodes.respondToNodeInsertion(*refNode);
1121 } 1121 }
1122 1122
1123 // Mutation events (bug 22634) may have already removed the inserted content 1123 // Mutation events (bug 22634) may have already removed the inserted content
1124 if (!refNode->inDocument()) 1124 if (!refNode->inDocument())
1125 return; 1125 return;
1126 1126
1127 bool plainTextFragment = isPlainTextMarkup(refNode.get()); 1127 bool plainTextFragment = isPlainTextMarkup(refNode.get());
1128 1128
1129 while (node) { 1129 while (node) {
1130 RefPtrWillBeRawPtr<Node> next = node->nextSibling(); 1130 RawPtr<Node> next = node->nextSibling();
1131 fragment.removeNode(node.get()); 1131 fragment.removeNode(node.get());
1132 insertNodeAfter(node, refNode); 1132 insertNodeAfter(node, refNode);
1133 insertedNodes.respondToNodeInsertion(*node); 1133 insertedNodes.respondToNodeInsertion(*node);
1134 1134
1135 // Mutation events (bug 22634) may have already removed the inserted con tent 1135 // Mutation events (bug 22634) may have already removed the inserted con tent
1136 if (!node->inDocument()) 1136 if (!node->inDocument())
1137 return; 1137 return;
1138 1138
1139 refNode = node; 1139 refNode = node;
1140 if (node && plainTextFragment) 1140 if (node && plainTextFragment)
(...skipping 16 matching lines...) Expand all
1157 enclosingBlockOfInsertionPos = nullptr; 1157 enclosingBlockOfInsertionPos = nullptr;
1158 1158
1159 VisiblePosition startOfInsertedContent = createVisiblePosition(firstPosition InOrBeforeNode(insertedNodes.firstNodeInserted())); 1159 VisiblePosition startOfInsertedContent = createVisiblePosition(firstPosition InOrBeforeNode(insertedNodes.firstNodeInserted()));
1160 1160
1161 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a nd 1161 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a nd
1162 // didn't have a br after it, so the inserted content ended up in the same p aragraph. 1162 // didn't have a br after it, so the inserted content ended up in the same p aragraph.
1163 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned )insertionPos.computeEditingOffset() < enclosingBlockOfInsertionPos->nodeIndex() && !isStartOfParagraph(startOfInsertedContent)) 1163 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned )insertionPos.computeEditingOffset() < enclosingBlockOfInsertionPos->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
1164 insertNodeAt(HTMLBRElement::create(document()).get(), startOfInsertedCon tent.deepEquivalent()); 1164 insertNodeAt(HTMLBRElement::create(document()).get(), startOfInsertedCon tent.deepEquivalent());
1165 1165
1166 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)) )) { 1166 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)) )) {
1167 RefPtrWillBeRawPtr<ContainerNode> parent = endBR->parentNode(); 1167 RawPtr<ContainerNode> parent = endBR->parentNode();
1168 insertedNodes.willRemoveNode(*endBR); 1168 insertedNodes.willRemoveNode(*endBR);
1169 removeNode(endBR); 1169 removeNode(endBR);
1170 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) { 1170 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) {
1171 insertedNodes.willRemoveNode(*nodeToRemove); 1171 insertedNodes.willRemoveNode(*nodeToRemove);
1172 removeNode(nodeToRemove); 1172 removeNode(nodeToRemove);
1173 } 1173 }
1174 } 1174 }
1175 1175
1176 makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes); 1176 makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes);
1177 1177
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 Position lastPositionToSelect; 1224 Position lastPositionToSelect;
1225 if (fragment.hasInterchangeNewlineAtEnd()) { 1225 if (fragment.hasInterchangeNewlineAtEnd()) {
1226 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); 1226 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
1227 VisiblePosition next = nextPositionOf(endOfInsertedContent, CannotCrossE ditingBoundary); 1227 VisiblePosition next = nextPositionOf(endOfInsertedContent, CannotCrossE ditingBoundary);
1228 1228
1229 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont ent) || next.isNull()) { 1229 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont ent) || next.isNull()) {
1230 if (!isStartOfParagraph(endOfInsertedContent)) { 1230 if (!isStartOfParagraph(endOfInsertedContent)) {
1231 setEndingSelection(endOfInsertedContent); 1231 setEndingSelection(endOfInsertedContent);
1232 Element* enclosingBlockElement = enclosingBlock(endOfInsertedCon tent.deepEquivalent().anchorNode()); 1232 Element* enclosingBlockElement = enclosingBlock(endOfInsertedCon tent.deepEquivalent().anchorNode());
1233 if (isListItem(enclosingBlockElement)) { 1233 if (isListItem(enclosingBlockElement)) {
1234 RefPtrWillBeRawPtr<HTMLLIElement> newListItem = HTMLLIElemen t::create(document()); 1234 RawPtr<HTMLLIElement> newListItem = HTMLLIElement::create(do cument());
1235 insertNodeAfter(newListItem, enclosingBlockElement); 1235 insertNodeAfter(newListItem, enclosingBlockElement);
1236 setEndingSelection(createVisiblePosition(firstPositionInNode (newListItem.get()))); 1236 setEndingSelection(createVisiblePosition(firstPositionInNode (newListItem.get())));
1237 } else { 1237 } else {
1238 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph 1238 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph
1239 // block's style seems to annoy users. 1239 // block's style seems to annoy users.
1240 insertParagraphSeparator(true, !startIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(), 1240 insertParagraphSeparator(true, !startIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(),
1241 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary, insertedNodes.firstNodeInserted()->parentNode())); 1241 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary, insertedNodes.firstNodeInserted()->parentNode()));
1242 } 1242 }
1243 1243
1244 // Select up to the paragraph separator that was added. 1244 // Select up to the paragraph separator that was added.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 } 1318 }
1319 1319
1320 bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) && !isChar acterSmartReplaceExemptConsideringNonBreakingSpace(characterAfter(endOfInsertedC ontent), false); 1320 bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) && !isChar acterSmartReplaceExemptConsideringNonBreakingSpace(characterAfter(endOfInsertedC ontent), false);
1321 if (needsTrailingSpace && endNode) { 1321 if (needsTrailingSpace && endNode) {
1322 bool collapseWhiteSpace = !endNode->layoutObject() || endNode->layoutObj ect()->style()->collapseWhiteSpace(); 1322 bool collapseWhiteSpace = !endNode->layoutObject() || endNode->layoutObj ect()->style()->collapseWhiteSpace();
1323 if (endNode->isTextNode()) { 1323 if (endNode->isTextNode()) {
1324 insertTextIntoNode(toText(endNode), endOffset, collapseWhiteSpace ? nonBreakingSpaceString() : " "); 1324 insertTextIntoNode(toText(endNode), endOffset, collapseWhiteSpace ? nonBreakingSpaceString() : " ");
1325 if (m_endOfInsertedContent.computeContainerNode() == endNode) 1325 if (m_endOfInsertedContent.computeContainerNode() == endNode)
1326 m_endOfInsertedContent = Position(endNode, m_endOfInsertedConten t.offsetInContainerNode() + 1); 1326 m_endOfInsertedContent = Position(endNode, m_endOfInsertedConten t.offsetInContainerNode() + 1);
1327 } else { 1327 } else {
1328 RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(col lapseWhiteSpace ? nonBreakingSpaceString() : " "); 1328 RawPtr<Text> node = document().createEditingTextNode(collapseWhiteSp ace ? nonBreakingSpaceString() : " ");
1329 insertNodeAfter(node, endNode); 1329 insertNodeAfter(node, endNode);
1330 updateNodesInserted(node.get()); 1330 updateNodesInserted(node.get());
1331 } 1331 }
1332 } 1332 }
1333 1333
1334 document().updateLayout(); 1334 document().updateLayout();
1335 1335
1336 Position startDownstream = mostForwardCaretPosition(startOfInsertedContent.d eepEquivalent()); 1336 Position startDownstream = mostForwardCaretPosition(startOfInsertedContent.d eepEquivalent());
1337 Node* startNode = startDownstream.computeNodeAfterPosition(); 1337 Node* startNode = startDownstream.computeNodeAfterPosition();
1338 unsigned startOffset = 0; 1338 unsigned startOffset = 0;
1339 if (startDownstream.isOffsetInAnchor()) { 1339 if (startDownstream.isOffsetInAnchor()) {
1340 startNode = startDownstream.computeContainerNode(); 1340 startNode = startDownstream.computeContainerNode();
1341 startOffset = startDownstream.offsetInContainerNode(); 1341 startOffset = startDownstream.offsetInContainerNode();
1342 } 1342 }
1343 1343
1344 bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) && !isC haracterSmartReplaceExemptConsideringNonBreakingSpace(characterBefore(startOfIns ertedContent), true); 1344 bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) && !isC haracterSmartReplaceExemptConsideringNonBreakingSpace(characterBefore(startOfIns ertedContent), true);
1345 if (needsLeadingSpace && startNode) { 1345 if (needsLeadingSpace && startNode) {
1346 bool collapseWhiteSpace = !startNode->layoutObject() || startNode->layou tObject()->style()->collapseWhiteSpace(); 1346 bool collapseWhiteSpace = !startNode->layoutObject() || startNode->layou tObject()->style()->collapseWhiteSpace();
1347 if (startNode->isTextNode()) { 1347 if (startNode->isTextNode()) {
1348 insertTextIntoNode(toText(startNode), startOffset, collapseWhiteSpac e ? nonBreakingSpaceString() : " "); 1348 insertTextIntoNode(toText(startNode), startOffset, collapseWhiteSpac e ? nonBreakingSpaceString() : " ");
1349 if (m_endOfInsertedContent.computeContainerNode() == startNode && m_ endOfInsertedContent.offsetInContainerNode()) 1349 if (m_endOfInsertedContent.computeContainerNode() == startNode && m_ endOfInsertedContent.offsetInContainerNode())
1350 m_endOfInsertedContent = Position(startNode, m_endOfInsertedCont ent.offsetInContainerNode() + 1); 1350 m_endOfInsertedContent = Position(startNode, m_endOfInsertedCont ent.offsetInContainerNode() + 1);
1351 } else { 1351 } else {
1352 RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(col lapseWhiteSpace ? nonBreakingSpaceString() : " "); 1352 RawPtr<Text> node = document().createEditingTextNode(collapseWhiteSp ace ? nonBreakingSpaceString() : " ");
1353 // Don't updateNodesInserted. Doing so would set m_endOfInsertedCont ent to be the node containing the leading space, 1353 // Don't updateNodesInserted. Doing so would set m_endOfInsertedCont ent to be the node containing the leading space,
1354 // but m_endOfInsertedContent is supposed to mark the end of pasted content. 1354 // but m_endOfInsertedContent is supposed to mark the end of pasted content.
1355 insertNodeBefore(node, startNode); 1355 insertNodeBefore(node, startNode);
1356 m_startOfInsertedContent = firstPositionInNode(node.get()); 1356 m_startOfInsertedContent = firstPositionInNode(node.get());
1357 } 1357 }
1358 } 1358 }
1359 } 1359 }
1360 1360
1361 void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi onToSelect) 1361 void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi onToSelect)
1362 { 1362 {
(...skipping 27 matching lines...) Expand all
1390 if (m_selectReplacement) 1390 if (m_selectReplacement)
1391 setEndingSelection(VisibleSelection(start, end, SelDefaultAffinity, endi ngSelection().isDirectional())); 1391 setEndingSelection(VisibleSelection(start, end, SelDefaultAffinity, endi ngSelection().isDirectional()));
1392 else 1392 else
1393 setEndingSelection(VisibleSelection(end, SelDefaultAffinity, endingSelec tion().isDirectional())); 1393 setEndingSelection(VisibleSelection(end, SelDefaultAffinity, endingSelec tion().isDirectional()));
1394 } 1394 }
1395 1395
1396 void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P osition& positionOnlyToBeUpdated) 1396 void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P osition& positionOnlyToBeUpdated)
1397 { 1397 {
1398 bool positionIsOffsetInAnchor = position.isOffsetInAnchor(); 1398 bool positionIsOffsetInAnchor = position.isOffsetInAnchor();
1399 bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.isOff setInAnchor(); 1399 bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.isOff setInAnchor();
1400 RefPtrWillBeRawPtr<Text> text = nullptr; 1400 RawPtr<Text> text = nullptr;
1401 if (positionIsOffsetInAnchor && position.computeContainerNode() && position. computeContainerNode()->isTextNode()) { 1401 if (positionIsOffsetInAnchor && position.computeContainerNode() && position. computeContainerNode()->isTextNode()) {
1402 text = toText(position.computeContainerNode()); 1402 text = toText(position.computeContainerNode());
1403 } else { 1403 } else {
1404 Node* before = position.computeNodeBeforePosition(); 1404 Node* before = position.computeNodeBeforePosition();
1405 if (before && before->isTextNode()) { 1405 if (before && before->isTextNode()) {
1406 text = toText(before); 1406 text = toText(before);
1407 } else { 1407 } else {
1408 Node* after = position.computeNodeAfterPosition(); 1408 Node* after = position.computeNodeAfterPosition();
1409 if (after && after->isTextNode()) 1409 if (after && after->isTextNode())
1410 text = toText(after); 1410 text = toText(after);
1411 } 1411 }
1412 } 1412 }
1413 if (!text) 1413 if (!text)
1414 return; 1414 return;
1415 1415
1416 if (text->previousSibling() && text->previousSibling()->isTextNode()) { 1416 if (text->previousSibling() && text->previousSibling()->isTextNode()) {
1417 RefPtrWillBeRawPtr<Text> previous = toText(text->previousSibling()); 1417 RawPtr<Text> previous = toText(text->previousSibling());
1418 insertTextIntoNode(text, 0, previous->data()); 1418 insertTextIntoNode(text, 0, previous->data());
1419 1419
1420 if (positionIsOffsetInAnchor) 1420 if (positionIsOffsetInAnchor)
1421 position = Position(position.computeContainerNode(), previous->lengt h() + position.offsetInContainerNode()); 1421 position = Position(position.computeContainerNode(), previous->lengt h() + position.offsetInContainerNode());
1422 else 1422 else
1423 updatePositionForNodeRemoval(position, *previous); 1423 updatePositionForNodeRemoval(position, *previous);
1424 1424
1425 if (positionOnlyToBeUpdatedIsOffsetInAnchor) { 1425 if (positionOnlyToBeUpdatedIsOffsetInAnchor) {
1426 if (positionOnlyToBeUpdated.computeContainerNode() == text) 1426 if (positionOnlyToBeUpdated.computeContainerNode() == text)
1427 positionOnlyToBeUpdated = Position(text, previous->length() + po sitionOnlyToBeUpdated.offsetInContainerNode()); 1427 positionOnlyToBeUpdated = Position(text, previous->length() + po sitionOnlyToBeUpdated.offsetInContainerNode());
1428 else if (positionOnlyToBeUpdated.computeContainerNode() == previous) 1428 else if (positionOnlyToBeUpdated.computeContainerNode() == previous)
1429 positionOnlyToBeUpdated = Position(text, positionOnlyToBeUpdated .offsetInContainerNode()); 1429 positionOnlyToBeUpdated = Position(text, positionOnlyToBeUpdated .offsetInContainerNode());
1430 } else { 1430 } else {
1431 updatePositionForNodeRemoval(positionOnlyToBeUpdated, *previous); 1431 updatePositionForNodeRemoval(positionOnlyToBeUpdated, *previous);
1432 } 1432 }
1433 1433
1434 removeNode(previous); 1434 removeNode(previous);
1435 } 1435 }
1436 if (text->nextSibling() && text->nextSibling()->isTextNode()) { 1436 if (text->nextSibling() && text->nextSibling()->isTextNode()) {
1437 RefPtrWillBeRawPtr<Text> next = toText(text->nextSibling()); 1437 RawPtr<Text> next = toText(text->nextSibling());
1438 unsigned originalLength = text->length(); 1438 unsigned originalLength = text->length();
1439 insertTextIntoNode(text, originalLength, next->data()); 1439 insertTextIntoNode(text, originalLength, next->data());
1440 1440
1441 if (!positionIsOffsetInAnchor) 1441 if (!positionIsOffsetInAnchor)
1442 updatePositionForNodeRemoval(position, *next); 1442 updatePositionForNodeRemoval(position, *next);
1443 1443
1444 if (positionOnlyToBeUpdatedIsOffsetInAnchor && positionOnlyToBeUpdated.c omputeContainerNode() == next) 1444 if (positionOnlyToBeUpdatedIsOffsetInAnchor && positionOnlyToBeUpdated.c omputeContainerNode() == next)
1445 positionOnlyToBeUpdated = Position(text, originalLength + positionOn lyToBeUpdated.offsetInContainerNode()); 1445 positionOnlyToBeUpdated = Position(text, originalLength + positionOn lyToBeUpdated.offsetInContainerNode());
1446 else 1446 else
1447 updatePositionForNodeRemoval(positionOnlyToBeUpdated, *next); 1447 updatePositionForNodeRemoval(positionOnlyToBeUpdated, *next);
1448 1448
1449 removeNode(next); 1449 removeNode(next);
1450 } 1450 }
1451 } 1451 }
1452 1452
1453 EditAction ReplaceSelectionCommand::editingAction() const 1453 EditAction ReplaceSelectionCommand::editingAction() const
1454 { 1454 {
1455 return m_editAction; 1455 return m_editAction;
1456 } 1456 }
1457 1457
1458 // If the user is inserting a list into an existing list, instead of nesting the list, 1458 // If the user is inserting a list into an existing list, instead of nesting the list,
1459 // we put the list items into the existing list. 1459 // we put the list items into the existing list.
1460 Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtrWillBeRawPtr<HTMLElem ent> prpListElement, Element* insertionBlock, const Position& insertPos, Inserte dNodes& insertedNodes) 1460 Node* ReplaceSelectionCommand::insertAsListItems(RawPtr<HTMLElement> prpListElem ent, Element* insertionBlock, const Position& insertPos, InsertedNodes& inserted Nodes)
1461 { 1461 {
1462 RefPtrWillBeRawPtr<HTMLElement> listElement = prpListElement; 1462 RawPtr<HTMLElement> listElement = prpListElement;
1463 1463
1464 while (listElement->hasOneChild() && isHTMLListElement(listElement->firstChi ld())) 1464 while (listElement->hasOneChild() && isHTMLListElement(listElement->firstChi ld()))
1465 listElement = toHTMLElement(listElement->firstChild()); 1465 listElement = toHTMLElement(listElement->firstChild());
1466 1466
1467 bool isStart = isStartOfParagraph(createVisiblePosition(insertPos)); 1467 bool isStart = isStartOfParagraph(createVisiblePosition(insertPos));
1468 bool isEnd = isEndOfParagraph(createVisiblePosition(insertPos)); 1468 bool isEnd = isEndOfParagraph(createVisiblePosition(insertPos));
1469 bool isMiddle = !isStart && !isEnd; 1469 bool isMiddle = !isStart && !isEnd;
1470 Node* lastNode = insertionBlock; 1470 Node* lastNode = insertionBlock;
1471 1471
1472 // If we're in the middle of a list item, we should split it into two separa te 1472 // If we're in the middle of a list item, we should split it into two separa te
1473 // list items and insert these nodes between them. 1473 // list items and insert these nodes between them.
1474 if (isMiddle) { 1474 if (isMiddle) {
1475 int textNodeOffset = insertPos.offsetInContainerNode(); 1475 int textNodeOffset = insertPos.offsetInContainerNode();
1476 if (insertPos.anchorNode()->isTextNode() && textNodeOffset > 0) 1476 if (insertPos.anchorNode()->isTextNode() && textNodeOffset > 0)
1477 splitTextNode(toText(insertPos.anchorNode()), textNodeOffset); 1477 splitTextNode(toText(insertPos.anchorNode()), textNodeOffset);
1478 splitTreeToNode(insertPos.anchorNode(), lastNode, true); 1478 splitTreeToNode(insertPos.anchorNode(), lastNode, true);
1479 } 1479 }
1480 1480
1481 while (RefPtrWillBeRawPtr<Node> listItem = listElement->firstChild()) { 1481 while (RawPtr<Node> listItem = listElement->firstChild()) {
1482 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION); 1482 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION);
1483 if (isStart || isMiddle) { 1483 if (isStart || isMiddle) {
1484 insertNodeBefore(listItem, lastNode); 1484 insertNodeBefore(listItem, lastNode);
1485 insertedNodes.respondToNodeInsertion(*listItem); 1485 insertedNodes.respondToNodeInsertion(*listItem);
1486 } else if (isEnd) { 1486 } else if (isEnd) {
1487 insertNodeAfter(listItem, lastNode); 1487 insertNodeAfter(listItem, lastNode);
1488 insertedNodes.respondToNodeInsertion(*listItem); 1488 insertedNodes.respondToNodeInsertion(*listItem);
1489 lastNode = listItem.get(); 1489 lastNode = listItem.get();
1490 } else { 1490 } else {
1491 ASSERT_NOT_REACHED(); 1491 ASSERT_NOT_REACHED();
(...skipping 27 matching lines...) Expand all
1519 return false; 1519 return false;
1520 1520
1521 // FIXME: Would be nice to handle smart replace in the fast path. 1521 // FIXME: Would be nice to handle smart replace in the fast path.
1522 if (m_smartReplace || fragment.hasInterchangeNewlineAtStart() || fragment.ha sInterchangeNewlineAtEnd()) 1522 if (m_smartReplace || fragment.hasInterchangeNewlineAtStart() || fragment.ha sInterchangeNewlineAtEnd())
1523 return false; 1523 return false;
1524 1524
1525 // e.g. when "bar" is inserted after "foo" in <div><u>foo</u></div>, "bar" s hould not be underlined. 1525 // e.g. when "bar" is inserted after "foo" in <div><u>foo</u></div>, "bar" s hould not be underlined.
1526 if (elementToSplitToAvoidPastingIntoInlineElementsWithStyle(endingSelection( ).start())) 1526 if (elementToSplitToAvoidPastingIntoInlineElementsWithStyle(endingSelection( ).start()))
1527 return false; 1527 return false;
1528 1528
1529 RefPtrWillBeRawPtr<Node> nodeAfterInsertionPos = mostForwardCaretPosition(en dingSelection().end()).anchorNode(); 1529 RawPtr<Node> nodeAfterInsertionPos = mostForwardCaretPosition(endingSelectio n().end()).anchorNode();
1530 Text* textNode = toText(fragment.firstChild()); 1530 Text* textNode = toText(fragment.firstChild());
1531 // Our fragment creation code handles tabs, spaces, and newlines, so we don' t have to worry about those here. 1531 // Our fragment creation code handles tabs, spaces, and newlines, so we don' t have to worry about those here.
1532 1532
1533 Position start = endingSelection().start(); 1533 Position start = endingSelection().start();
1534 Position end = replaceSelectedTextInNode(textNode->data()); 1534 Position end = replaceSelectedTextInNode(textNode->data());
1535 if (end.isNull()) 1535 if (end.isNull())
1536 return false; 1536 return false;
1537 1537
1538 if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBR Element(*nodeAfterInsertionPos) 1538 if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBR Element(*nodeAfterInsertionPos)
1539 && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), creat eVisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) 1539 && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), creat eVisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get()))))
(...skipping 24 matching lines...) Expand all
1564 visitor->trace(m_startOfInsertedContent); 1564 visitor->trace(m_startOfInsertedContent);
1565 visitor->trace(m_endOfInsertedContent); 1565 visitor->trace(m_endOfInsertedContent);
1566 visitor->trace(m_insertionStyle); 1566 visitor->trace(m_insertionStyle);
1567 visitor->trace(m_documentFragment); 1567 visitor->trace(m_documentFragment);
1568 visitor->trace(m_startOfInsertedRange); 1568 visitor->trace(m_startOfInsertedRange);
1569 visitor->trace(m_endOfInsertedRange); 1569 visitor->trace(m_endOfInsertedRange);
1570 CompositeEditCommand::trace(visitor); 1570 CompositeEditCommand::trace(visitor);
1571 } 1571 }
1572 1572
1573 } // namespace blink 1573 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698