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

Side by Side Diff: Source/core/editing/ReplaceSelectionCommand.cpp

Issue 299353004: Oilpan: move editing objects to the heap. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 7 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 ReplacementFragment(Document*, DocumentFragment*, const VisibleSelection&); 70 ReplacementFragment(Document*, DocumentFragment*, const VisibleSelection&);
71 71
72 Node* firstChild() const; 72 Node* firstChild() const;
73 Node* lastChild() const; 73 Node* lastChild() const;
74 74
75 bool isEmpty() const; 75 bool isEmpty() const;
76 76
77 bool hasInterchangeNewlineAtStart() const { return m_hasInterchangeNewlineAt Start; } 77 bool hasInterchangeNewlineAtStart() const { return m_hasInterchangeNewlineAt Start; }
78 bool hasInterchangeNewlineAtEnd() const { return m_hasInterchangeNewlineAtEn d; } 78 bool hasInterchangeNewlineAtEnd() const { return m_hasInterchangeNewlineAtEn d; }
79 79
80 void removeNode(PassRefPtr<Node>); 80 void removeNode(PassRefPtrWillBeRawPtr<Node>);
81 void removeNodePreservingChildren(PassRefPtr<Node>); 81 void removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node>);
82 82
83 private: 83 private:
84 PassRefPtr<Element> insertFragmentForTestRendering(Node* rootEditableNode); 84 PassRefPtrWillBeRawPtr<Element> insertFragmentForTestRendering(Node* rootEdi tableNode);
85 void removeUnrenderedNodes(Node*); 85 void removeUnrenderedNodes(Node*);
86 void restoreAndRemoveTestRenderingNodesToFragment(Element*); 86 void restoreAndRemoveTestRenderingNodesToFragment(Element*);
87 void removeInterchangeNodes(Node*); 87 void removeInterchangeNodes(Node*);
88 88
89 void insertNodeBefore(PassRefPtr<Node> node, Node* refNode); 89 void insertNodeBefore(PassRefPtrWillBeRawPtr<Node>, Node* refNode);
90 90
91 RefPtrWillBeMember<Document> m_document; 91 RefPtrWillBeMember<Document> m_document;
92 RefPtrWillBeMember<DocumentFragment> m_fragment; 92 RefPtrWillBeMember<DocumentFragment> m_fragment;
93 bool m_hasInterchangeNewlineAtStart; 93 bool m_hasInterchangeNewlineAtStart;
94 bool m_hasInterchangeNewlineAtEnd; 94 bool m_hasInterchangeNewlineAtEnd;
95 }; 95 };
96 96
97 static bool isInterchangeNewlineNode(const Node *node) 97 static bool isInterchangeNewlineNode(const Node *node)
98 { 98 {
99 DEFINE_STATIC_LOCAL(String, interchangeNewlineClassString, (AppleInterchange Newline)); 99 DEFINE_STATIC_LOCAL(String, interchangeNewlineClassString, (AppleInterchange Newline));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 m_hasInterchangeNewlineAtStart(false), 138 m_hasInterchangeNewlineAtStart(false),
139 m_hasInterchangeNewlineAtEnd(false) 139 m_hasInterchangeNewlineAtEnd(false)
140 { 140 {
141 if (!m_document) 141 if (!m_document)
142 return; 142 return;
143 if (!m_fragment) 143 if (!m_fragment)
144 return; 144 return;
145 if (!m_fragment->firstChild()) 145 if (!m_fragment->firstChild())
146 return; 146 return;
147 147
148 RefPtr<Element> editableRoot = selection.rootEditableElement(); 148 RefPtrWillBeRawPtr<Element> editableRoot = selection.rootEditableElement();
149 ASSERT(editableRoot); 149 ASSERT(editableRoot);
150 if (!editableRoot) 150 if (!editableRoot)
151 return; 151 return;
152 152
153 Node* shadowAncestorNode = editableRoot->deprecatedShadowAncestorNode(); 153 Node* shadowAncestorNode = editableRoot->deprecatedShadowAncestorNode();
154 154
155 if (!editableRoot->getAttributeEventListener(EventTypeNames::webkitBeforeTex tInserted) && 155 if (!editableRoot->getAttributeEventListener(EventTypeNames::webkitBeforeTex tInserted) &&
156 // FIXME: Remove these checks once textareas and textfields actually reg ister an event handler. 156 // FIXME: Remove these checks once textareas and textfields actually reg ister an event handler.
157 !(shadowAncestorNode && shadowAncestorNode->renderer() && shadowAncestor Node->renderer()->isTextControl()) && 157 !(shadowAncestorNode && shadowAncestorNode->renderer() && shadowAncestor Node->renderer()->isTextControl()) &&
158 editableRoot->rendererIsRichlyEditable()) { 158 editableRoot->rendererIsRichlyEditable()) {
159 removeInterchangeNodes(m_fragment.get()); 159 removeInterchangeNodes(m_fragment.get());
160 return; 160 return;
161 } 161 }
162 162
163 RefPtr<Element> holder = insertFragmentForTestRendering(editableRoot.get()); 163 RefPtrWillBeRawPtr<Element> holder = insertFragmentForTestRendering(editable Root.get());
164 if (!holder) { 164 if (!holder) {
165 removeInterchangeNodes(m_fragment.get()); 165 removeInterchangeNodes(m_fragment.get());
166 return; 166 return;
167 } 167 }
168 168
169 RefPtrWillBeRawPtr<Range> range = VisibleSelection::selectionFromContentsOfN ode(holder.get()).toNormalizedRange(); 169 RefPtrWillBeRawPtr<Range> range = VisibleSelection::selectionFromContentsOfN ode(holder.get()).toNormalizedRange();
170 String text = plainText(range.get(), static_cast<TextIteratorBehavior>(TextI teratorEmitsOriginalText | TextIteratorIgnoresStyleVisibility)); 170 String text = plainText(range.get(), static_cast<TextIteratorBehavior>(TextI teratorEmitsOriginalText | TextIteratorIgnoresStyleVisibility));
171 171
172 removeInterchangeNodes(holder.get()); 172 removeInterchangeNodes(holder.get());
173 removeUnrenderedNodes(holder.get()); 173 removeUnrenderedNodes(holder.get());
(...skipping 24 matching lines...) Expand all
198 Node *ReplacementFragment::firstChild() const 198 Node *ReplacementFragment::firstChild() const
199 { 199 {
200 return m_fragment ? m_fragment->firstChild() : 0; 200 return m_fragment ? m_fragment->firstChild() : 0;
201 } 201 }
202 202
203 Node *ReplacementFragment::lastChild() const 203 Node *ReplacementFragment::lastChild() const
204 { 204 {
205 return m_fragment ? m_fragment->lastChild() : 0; 205 return m_fragment ? m_fragment->lastChild() : 0;
206 } 206 }
207 207
208 void ReplacementFragment::removeNodePreservingChildren(PassRefPtr<Node> node) 208 void ReplacementFragment::removeNodePreservingChildren(PassRefPtrWillBeRawPtr<No de> node)
209 { 209 {
210 if (!node) 210 if (!node)
211 return; 211 return;
212 212
213 while (RefPtr<Node> n = node->firstChild()) { 213 while (RefPtrWillBeRawPtr<Node> n = node->firstChild()) {
214 removeNode(n); 214 removeNode(n);
215 insertNodeBefore(n.release(), node.get()); 215 insertNodeBefore(n.release(), node.get());
216 } 216 }
217 removeNode(node); 217 removeNode(node);
218 } 218 }
219 219
220 void ReplacementFragment::removeNode(PassRefPtr<Node> node) 220 void ReplacementFragment::removeNode(PassRefPtrWillBeRawPtr<Node> node)
221 { 221 {
222 if (!node) 222 if (!node)
223 return; 223 return;
224 224
225 ContainerNode* parent = node->nonShadowBoundaryParentNode(); 225 ContainerNode* parent = node->nonShadowBoundaryParentNode();
226 if (!parent) 226 if (!parent)
227 return; 227 return;
228 228
229 parent->removeChild(node.get()); 229 parent->removeChild(node.get());
230 } 230 }
231 231
232 void ReplacementFragment::insertNodeBefore(PassRefPtr<Node> node, Node* refNode) 232 void ReplacementFragment::insertNodeBefore(PassRefPtrWillBeRawPtr<Node> node, No de* refNode)
233 { 233 {
234 if (!node || !refNode) 234 if (!node || !refNode)
235 return; 235 return;
236 236
237 ContainerNode* parent = refNode->nonShadowBoundaryParentNode(); 237 ContainerNode* parent = refNode->nonShadowBoundaryParentNode();
238 if (!parent) 238 if (!parent)
239 return; 239 return;
240 240
241 parent->insertBefore(node, refNode); 241 parent->insertBefore(node, refNode);
242 } 242 }
243 243
244 PassRefPtr<Element> ReplacementFragment::insertFragmentForTestRendering(Node* ro otEditableElement) 244 PassRefPtrWillBeRawPtr<Element> ReplacementFragment::insertFragmentForTestRender ing(Node* rootEditableElement)
245 { 245 {
246 ASSERT(m_document); 246 ASSERT(m_document);
247 RefPtr<Element> holder = createDefaultParagraphElement(*m_document.get()); 247 RefPtrWillBeRawPtr<Element> holder = createDefaultParagraphElement(*m_docume nt.get());
248 248
249 holder->appendChild(m_fragment); 249 holder->appendChild(m_fragment);
250 rootEditableElement->appendChild(holder.get()); 250 rootEditableElement->appendChild(holder.get());
251 m_document->updateLayoutIgnorePendingStylesheets(); 251 m_document->updateLayoutIgnorePendingStylesheets();
252 252
253 return holder.release(); 253 return holder.release();
254 } 254 }
255 255
256 void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element* holder) 256 void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element* holder)
257 { 257 {
258 if (!holder) 258 if (!holder)
259 return; 259 return;
260 260
261 while (RefPtr<Node> node = holder->firstChild()) { 261 while (RefPtrWillBeRawPtr<Node> node = holder->firstChild()) {
262 holder->removeChild(node.get()); 262 holder->removeChild(node.get());
263 m_fragment->appendChild(node.get()); 263 m_fragment->appendChild(node.get());
264 } 264 }
265 265
266 removeNode(holder); 266 removeNode(holder);
267 } 267 }
268 268
269 void ReplacementFragment::removeUnrenderedNodes(Node* holder) 269 void ReplacementFragment::removeUnrenderedNodes(Node* holder)
270 { 270 {
271 Vector<RefPtr<Node> > unrendered; 271 WillBeHeapVector<RefPtrWillBeMember<Node> > unrendered;
272 272
273 for (Node* node = holder->firstChild(); node; node = NodeTraversal::next(*no de, holder)) 273 for (Node* node = holder->firstChild(); node; node = NodeTraversal::next(*no de, holder))
274 if (!isNodeRendered(node) && !isTableStructureNode(node)) 274 if (!isNodeRendered(node) && !isTableStructureNode(node))
275 unrendered.append(node); 275 unrendered.append(node);
276 276
277 size_t n = unrendered.size(); 277 size_t n = unrendered.size();
278 for (size_t i = 0; i < n; ++i) 278 for (size_t i = 0; i < n; ++i)
279 removeNode(unrendered[i]); 279 removeNode(unrendered[i]);
280 } 280 }
281 281
(...skipping 22 matching lines...) Expand all
304 if (isInterchangeNewlineNode(node)) { 304 if (isInterchangeNewlineNode(node)) {
305 m_hasInterchangeNewlineAtEnd = true; 305 m_hasInterchangeNewlineAtEnd = true;
306 removeNode(node); 306 removeNode(node);
307 break; 307 break;
308 } 308 }
309 node = node->lastChild(); 309 node = node->lastChild();
310 } 310 }
311 311
312 node = container->firstChild(); 312 node = container->firstChild();
313 while (node) { 313 while (node) {
314 RefPtr<Node> next = NodeTraversal::next(*node); 314 RefPtrWillBeRawPtr<Node> next = NodeTraversal::next(*node);
315 if (isInterchangeConvertedSpaceSpan(node)) { 315 if (isInterchangeConvertedSpaceSpan(node)) {
316 next = NodeTraversal::nextSkippingChildren(*node); 316 next = NodeTraversal::nextSkippingChildren(*node);
317 removeNodePreservingChildren(node); 317 removeNodePreservingChildren(node);
318 } 318 }
319 node = next.get(); 319 node = next.get();
320 } 320 }
321 } 321 }
322 322
323 inline void ReplaceSelectionCommand::InsertedNodes::respondToNodeInsertion(Node& node) 323 inline void ReplaceSelectionCommand::InsertedNodes::respondToNodeInsertion(Node& node)
324 { 324 {
325 if (!m_firstNodeInserted) 325 if (!m_firstNodeInserted)
326 m_firstNodeInserted = &node; 326 m_firstNodeInserted = &node;
327 327
328 m_lastNodeInserted = &node; 328 m_lastNodeInserted = &node;
329 } 329 }
330 330
331 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNodePreservingChil dren(Node& node) 331 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNodePreservingChil dren(Node& node)
332 { 332 {
333 if (m_firstNodeInserted == node) 333 if (m_firstNodeInserted.get() == node)
334 m_firstNodeInserted = NodeTraversal::next(node); 334 m_firstNodeInserted = NodeTraversal::next(node);
335 if (m_lastNodeInserted == node) 335 if (m_lastNodeInserted.get() == node)
336 m_lastNodeInserted = node.lastChild() ? node.lastChild() : NodeTraversal ::nextSkippingChildren(node); 336 m_lastNodeInserted = node.lastChild() ? node.lastChild() : NodeTraversal ::nextSkippingChildren(node);
337 } 337 }
338 338
339 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNode(Node& node) 339 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNode(Node& node)
340 { 340 {
341 if (m_firstNodeInserted == node && m_lastNodeInserted == node) { 341 if (m_firstNodeInserted.get() == node && m_lastNodeInserted.get() == node) {
342 m_firstNodeInserted = nullptr; 342 m_firstNodeInserted = nullptr;
343 m_lastNodeInserted = nullptr; 343 m_lastNodeInserted = nullptr;
344 } else if (m_firstNodeInserted == node) { 344 } else if (m_firstNodeInserted.get() == node) {
345 m_firstNodeInserted = NodeTraversal::nextSkippingChildren(*m_firstNodeIn serted); 345 m_firstNodeInserted = NodeTraversal::nextSkippingChildren(*m_firstNodeIn serted);
346 } else if (m_lastNodeInserted == node) { 346 } else if (m_lastNodeInserted.get() == node) {
347 m_lastNodeInserted = NodeTraversal::previousSkippingChildren(*m_lastNode Inserted); 347 m_lastNodeInserted = NodeTraversal::previousSkippingChildren(*m_lastNode Inserted);
348 } 348 }
349 } 349 }
350 350
351 inline void ReplaceSelectionCommand::InsertedNodes::didReplaceNode(Node& node, N ode& newNode) 351 inline void ReplaceSelectionCommand::InsertedNodes::didReplaceNode(Node& node, N ode& newNode)
352 { 352 {
353 if (m_firstNodeInserted == node) 353 if (m_firstNodeInserted.get() == node)
354 m_firstNodeInserted = &newNode; 354 m_firstNodeInserted = &newNode;
355 if (m_lastNodeInserted == node) 355 if (m_lastNodeInserted.get() == node)
356 m_lastNodeInserted = &newNode; 356 m_lastNodeInserted = &newNode;
357 } 357 }
358 358
359 ReplaceSelectionCommand::ReplaceSelectionCommand(Document& document, PassRefPtrW illBeRawPtr<DocumentFragment> fragment, CommandOptions options, EditAction editA ction) 359 ReplaceSelectionCommand::ReplaceSelectionCommand(Document& document, PassRefPtrW illBeRawPtr<DocumentFragment> fragment, CommandOptions options, EditAction editA ction)
360 : CompositeEditCommand(document) 360 : CompositeEditCommand(document)
361 , m_selectReplacement(options & SelectReplacement) 361 , m_selectReplacement(options & SelectReplacement)
362 , m_smartReplace(options & SmartReplace) 362 , m_smartReplace(options & SmartReplace)
363 , m_matchStyle(options & MatchStyle) 363 , m_matchStyle(options & MatchStyle)
364 , m_documentFragment(fragment) 364 , m_documentFragment(fragment)
365 , m_preventNesting(options & PreventNesting) 365 , m_preventNesting(options & PreventNesting)
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 (!isHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, destin ationBlock)) && 455 (!isHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, destin ationBlock)) &&
456 // Don't merge to or from a position before or after a block because it would 456 // Don't merge to or from a position before or after a block because it would
457 // be a no-op and cause infinite recursion. 457 // be a no-op and cause infinite recursion.
458 !isBlock(sourceNode) && !isBlock(destinationNode); 458 !isBlock(sourceNode) && !isBlock(destinationNode);
459 } 459 }
460 460
461 // Style rules that match just inserted elements could change their appearance, like 461 // Style rules that match just inserted elements could change their appearance, like
462 // a div inserted into a document with div { display:inline; }. 462 // a div inserted into a document with div { display:inline; }.
463 void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert edNodes& insertedNodes) 463 void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert edNodes& insertedNodes)
464 { 464 {
465 RefPtr<Node> pastEndNode = insertedNodes.pastLastLeaf(); 465 RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
466 RefPtr<Node> next; 466 RefPtrWillBeRawPtr<Node> next;
haraken 2014/05/26 02:36:12 = nullptr;
sof 2014/05/28 08:31:35 Complied.
467 for (RefPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) { 467 for (RefPtrWillBeRawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) {
468 // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance 468 // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance
469 469
470 next = NodeTraversal::next(*node); 470 next = NodeTraversal::next(*node);
471 if (!node->isStyledElement()) 471 if (!node->isStyledElement())
472 continue; 472 continue;
473 473
474 Element* element = toElement(node); 474 Element* element = toElement(node);
475 475
476 const StylePropertySet* inlineStyle = element->inlineStyle(); 476 const StylePropertySet* inlineStyle = element->inlineStyle();
477 RefPtr<EditingStyle> newInlineStyle = EditingStyle::create(inlineStyle); 477 RefPtrWillBeRawPtr<EditingStyle> newInlineStyle = EditingStyle::create(i nlineStyle);
478 if (inlineStyle) { 478 if (inlineStyle) {
479 if (element->isHTMLElement()) { 479 if (element->isHTMLElement()) {
480 Vector<QualifiedName> attributes; 480 Vector<QualifiedName> attributes;
481 HTMLElement* htmlElement = toHTMLElement(element); 481 HTMLElement* htmlElement = toHTMLElement(element);
482 ASSERT(htmlElement); 482 ASSERT(htmlElement);
483 483
484 if (newInlineStyle->conflictsWithImplicitStyleOfElement(htmlElem ent)) { 484 if (newInlineStyle->conflictsWithImplicitStyleOfElement(htmlElem ent)) {
485 // e.g. <b style="font-weight: normal;"> is converted to <sp an style="font-weight: normal;"> 485 // e.g. <b style="font-weight: normal;"> is converted to <sp an style="font-weight: normal;">
486 node = replaceElementWithSpanPreservingChildrenAndAttributes (htmlElement); 486 node = replaceElementWithSpanPreservingChildrenAndAttributes (htmlElement);
487 element = toElement(node); 487 element = toElement(node);
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 elements.add(theadTag.localName()); 605 elements.add(theadTag.localName());
606 elements.add(trTag.localName()); 606 elements.add(trTag.localName());
607 elements.add(ulTag.localName()); 607 elements.add(ulTag.localName());
608 elements.add(xmpTag.localName()); 608 elements.add(xmpTag.localName());
609 } 609 }
610 return elements.contains(name); 610 return elements.contains(name);
611 } 611 }
612 612
613 void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuild er(const InsertedNodes& insertedNodes) 613 void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuild er(const InsertedNodes& insertedNodes)
614 { 614 {
615 RefPtr<Node> pastEndNode = insertedNodes.pastLastLeaf(); 615 RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
616 RefPtr<Node> next; 616 RefPtrWillBeRawPtr<Node> next;
haraken 2014/05/26 02:36:12 = nullptr;
sof 2014/05/28 08:31:35 Complied.
617 for (RefPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) { 617 for (RefPtrWillBeRawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) {
618 next = NodeTraversal::next(*node); 618 next = NodeTraversal::next(*node);
619 619
620 if (!node->isHTMLElement()) 620 if (!node->isHTMLElement())
621 continue; 621 continue;
622 622
623 if (isProhibitedParagraphChild(toHTMLElement(node)->localName())) { 623 if (isProhibitedParagraphChild(toHTMLElement(node)->localName())) {
624 if (HTMLElement* paragraphElement = toHTMLElement(enclosingNodeWithT ag(positionInParentBeforeNode(*node), pTag))) 624 if (HTMLElement* paragraphElement = toHTMLElement(enclosingNodeWithT ag(positionInParentBeforeNode(*node), pTag)))
625 moveNodeOutOfAncestor(node, paragraphElement); 625 moveNodeOutOfAncestor(node, paragraphElement);
626 } 626 }
627 627
628 if (isHeaderElement(node.get())) { 628 if (isHeaderElement(node.get())) {
629 if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeO fType(positionInParentBeforeNode(*node), isHeaderElement))) 629 if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeO fType(positionInParentBeforeNode(*node), isHeaderElement)))
630 moveNodeOutOfAncestor(node, headerElement); 630 moveNodeOutOfAncestor(node, headerElement);
631 } 631 }
632 } 632 }
633 } 633 }
634 634
635 void ReplaceSelectionCommand::moveNodeOutOfAncestor(PassRefPtr<Node> prpNode, Pa ssRefPtr<Node> prpAncestor) 635 void ReplaceSelectionCommand::moveNodeOutOfAncestor(PassRefPtrWillBeRawPtr<Node> prpNode, PassRefPtrWillBeRawPtr<Node> prpAncestor)
636 { 636 {
637 RefPtr<Node> node = prpNode; 637 RefPtrWillBeRawPtr<Node> node = prpNode;
638 RefPtr<Node> ancestor = prpAncestor; 638 RefPtrWillBeRawPtr<Node> ancestor = prpAncestor;
639 639
640 if (!ancestor->parentNode()->rendererIsEditable()) 640 if (!ancestor->parentNode()->rendererIsEditable())
641 return; 641 return;
642 642
643 VisiblePosition positionAtEndOfNode(lastPositionInOrAfterNode(node.get())); 643 VisiblePosition positionAtEndOfNode(lastPositionInOrAfterNode(node.get()));
644 VisiblePosition lastPositionInParagraph(lastPositionInNode(ancestor.get())); 644 VisiblePosition lastPositionInParagraph(lastPositionInNode(ancestor.get()));
645 if (positionAtEndOfNode == lastPositionInParagraph) { 645 if (positionAtEndOfNode == lastPositionInParagraph) {
646 removeNode(node); 646 removeNode(node);
647 if (ancestor->nextSibling()) 647 if (ancestor->nextSibling())
648 insertNodeBefore(node, ancestor->nextSibling()); 648 insertNodeBefore(node, ancestor->nextSibling());
649 else 649 else
650 appendNode(node, ancestor->parentNode()); 650 appendNode(node, ancestor->parentNode());
651 } else { 651 } else {
652 RefPtr<Node> nodeToSplitTo = splitTreeToNode(node.get(), ancestor.get(), true); 652 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(node.get(), anc estor.get(), true);
653 removeNode(node); 653 removeNode(node);
654 insertNodeBefore(node, nodeToSplitTo); 654 insertNodeBefore(node, nodeToSplitTo);
655 } 655 }
656 if (!ancestor->firstChild()) 656 if (!ancestor->firstChild())
657 removeNode(ancestor.release()); 657 removeNode(ancestor.release());
658 } 658 }
659 659
660 static inline bool nodeHasVisibleRenderText(Text& text) 660 static inline bool nodeHasVisibleRenderText(Text& text)
661 { 661 {
662 return text.renderer() && toRenderText(text.renderer())->renderedTextLength( ) > 0; 662 return text.renderer() && toRenderText(text.renderer())->renderedTextLength( ) > 0;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 // and doesn't receive the optimization. 722 // and doesn't receive the optimization.
723 if (isMailPasteAsQuotationNode(topNode) || enclosingNodeOfType(firstPosition InOrBeforeNode(topNode), isMailBlockquote, CanCrossEditingBoundary)) 723 if (isMailPasteAsQuotationNode(topNode) || enclosingNodeOfType(firstPosition InOrBeforeNode(topNode), isMailBlockquote, CanCrossEditingBoundary))
724 return false; 724 return false;
725 725
726 // Either there are no style spans in the fragment or a WebKit client has ad ded content to the fragment 726 // Either there are no style spans in the fragment or a WebKit client has ad ded content to the fragment
727 // before inserting it. Look for and handle style spans after insertion. 727 // before inserting it. Look for and handle style spans after insertion.
728 if (!isLegacyAppleStyleSpan(topNode)) 728 if (!isLegacyAppleStyleSpan(topNode))
729 return false; 729 return false;
730 730
731 Node* wrappingStyleSpan = topNode; 731 Node* wrappingStyleSpan = topNode;
732 RefPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create(insertionPos .parentAnchoredEquivalent()); 732 RefPtrWillBeRawPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create( insertionPos.parentAnchoredEquivalent());
733 String styleText = styleAtInsertionPos->style()->asText(); 733 String styleText = styleAtInsertionPos->style()->asText();
734 734
735 // FIXME: This string comparison is a naive way of comparing two styles. 735 // FIXME: This string comparison is a naive way of comparing two styles.
736 // We should be taking the diff and check that the diff is empty. 736 // We should be taking the diff and check that the diff is empty.
737 if (styleText != toElement(wrappingStyleSpan)->getAttribute(styleAttr)) 737 if (styleText != toElement(wrappingStyleSpan)->getAttribute(styleAttr))
738 return false; 738 return false;
739 739
740 fragment.removeNodePreservingChildren(wrappingStyleSpan); 740 fragment.removeNodePreservingChildren(wrappingStyleSpan);
741 return true; 741 return true;
742 } 742 }
(...skipping 17 matching lines...) Expand all
760 wrappingStyleSpan = toHTMLElement(node); 760 wrappingStyleSpan = toHTMLElement(node);
761 break; 761 break;
762 } 762 }
763 } 763 }
764 764
765 // There might not be any style spans if we're pasting from another applicat ion or if 765 // There might not be any style spans if we're pasting from another applicat ion or if
766 // we are here because of a document.execCommand("InsertHTML", ...) call. 766 // we are here because of a document.execCommand("InsertHTML", ...) call.
767 if (!wrappingStyleSpan) 767 if (!wrappingStyleSpan)
768 return; 768 return;
769 769
770 RefPtr<EditingStyle> style = EditingStyle::create(wrappingStyleSpan->inlineS tyle()); 770 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(wrappingStyleS pan->inlineStyle());
771 ContainerNode* context = wrappingStyleSpan->parentNode(); 771 ContainerNode* context = wrappingStyleSpan->parentNode();
772 772
773 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if yo u're pasting into a quoted region, 773 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if yo u're pasting into a quoted region,
774 // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>. 774 // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>.
775 Node* blockquoteNode = isMailPasteAsQuotationNode(context) ? context : enclo singNodeOfType(firstPositionInNode(context), isMailBlockquote, CanCrossEditingBo undary); 775 Node* blockquoteNode = isMailPasteAsQuotationNode(context) ? context : enclo singNodeOfType(firstPositionInNode(context), isMailBlockquote, CanCrossEditingBo undary);
776 if (blockquoteNode) 776 if (blockquoteNode)
777 context = document().documentElement(); 777 context = document().documentElement();
778 778
779 // This operation requires that only editing styles to be removed from sourc eDocumentStyle. 779 // This operation requires that only editing styles to be removed from sourc eDocumentStyle.
780 style->prepareToApplyAt(firstPositionInNode(context)); 780 style->prepareToApplyAt(firstPositionInNode(context));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 // include the what was the start of the selection that was pasted into, so that we preserve that paragraph's 813 // include the what was the start of the selection that was pasted into, so that we preserve that paragraph's
814 // block styles. 814 // block styles.
815 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC ontent) && !isStartOfParagraph(startOfInsertedContent)); 815 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC ontent) && !isStartOfParagraph(startOfInsertedContent));
816 816
817 VisiblePosition destination = mergeForward ? endOfInsertedContent.next() : e ndOfInsertedContent; 817 VisiblePosition destination = mergeForward ? endOfInsertedContent.next() : e ndOfInsertedContent;
818 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end OfInsertedContent) : endOfInsertedContent.next(); 818 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end OfInsertedContent) : endOfInsertedContent.next();
819 819
820 // Merging forward could result in deleting the destination anchor node. 820 // Merging forward could result in deleting the destination anchor node.
821 // To avoid this, we add a placeholder node before the start of the paragrap h. 821 // To avoid this, we add a placeholder node before the start of the paragrap h.
822 if (endOfParagraph(startOfParagraphToMove) == destination) { 822 if (endOfParagraph(startOfParagraphToMove) == destination) {
823 RefPtr<Node> placeholder = createBreakElement(document()); 823 RefPtrWillBeRawPtr<Node> placeholder = createBreakElement(document());
824 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().de precatedNode()); 824 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().de precatedNode());
825 destination = VisiblePosition(positionBeforeNode(placeholder.get())); 825 destination = VisiblePosition(positionBeforeNode(placeholder.get()));
826 } 826 }
827 827
828 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove) , destination); 828 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove) , destination);
829 829
830 // Merging forward will remove m_endOfInsertedContent from the document. 830 // Merging forward will remove m_endOfInsertedContent from the document.
831 if (mergeForward) { 831 if (mergeForward) {
832 if (m_startOfInsertedContent.isOrphan()) 832 if (m_startOfInsertedContent.isOrphan())
833 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui valent(); 833 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui valent();
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 return; 986 return;
987 987
988 // NOTE: This would be an incorrect usage of downstream() if downstream() we re changed to mean the last position after 988 // NOTE: This would be an incorrect usage of downstream() if downstream() we re changed to mean the last position after
989 // 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 989 // 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
990 // away, there are positions after the br which map to the same visible posi tion as [br, 0]). 990 // away, there are positions after the br which map to the same visible posi tion as [br, 0]).
991 Node* endBR = isHTMLBRElement(*insertionPos.downstream().deprecatedNode()) ? insertionPos.downstream().deprecatedNode() : 0; 991 Node* endBR = isHTMLBRElement(*insertionPos.downstream().deprecatedNode()) ? insertionPos.downstream().deprecatedNode() : 0;
992 VisiblePosition originalVisPosBeforeEndBR; 992 VisiblePosition originalVisPosBeforeEndBR;
993 if (endBR) 993 if (endBR)
994 originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), D OWNSTREAM).previous(); 994 originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), D OWNSTREAM).previous();
995 995
996 RefPtr<Node> insertionBlock = enclosingBlock(insertionPos.deprecatedNode()); 996 RefPtrWillBeRawPtr<Node> insertionBlock = enclosingBlock(insertionPos.deprec atedNode());
997 997
998 // Adjust insertionPos to prevent nesting. 998 // Adjust insertionPos to prevent nesting.
999 // If the start was in a Mail blockquote, we will have already handled adjus ting insertionPos above. 999 // If the start was in a Mail blockquote, we will have already handled adjus ting insertionPos above.
1000 if (m_preventNesting && insertionBlock && !isTableCell(insertionBlock.get()) && !startIsInsideMailBlockquote) { 1000 if (m_preventNesting && insertionBlock && !isTableCell(insertionBlock.get()) && !startIsInsideMailBlockquote) {
1001 ASSERT(insertionBlock != currentRoot); 1001 ASSERT(insertionBlock != currentRoot);
1002 VisiblePosition visibleInsertionPos(insertionPos); 1002 VisiblePosition visibleInsertionPos(insertionPos);
1003 if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInserti onPos) && fragment.hasInterchangeNewlineAtEnd())) 1003 if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInserti onPos) && fragment.hasInterchangeNewlineAtEnd()))
1004 insertionPos = positionInParentAfterNode(*insertionBlock); 1004 insertionPos = positionInParentAfterNode(*insertionBlock);
1005 else if (isStartOfBlock(visibleInsertionPos)) 1005 else if (isStartOfBlock(visibleInsertionPos))
1006 insertionPos = positionInParentBeforeNode(*insertionBlock); 1006 insertionPos = positionInParentBeforeNode(*insertionBlock);
(...skipping 28 matching lines...) Expand all
1035 // This way we can produce a less verbose markup. 1035 // This way we can produce a less verbose markup.
1036 // We can skip this optimization for fragments not wrapped in one of 1036 // We can skip this optimization for fragments not wrapped in one of
1037 // our style spans and for positions inside list items 1037 // our style spans and for positions inside list items
1038 // since insertAsListItems already does the right thing. 1038 // since insertAsListItems already does the right thing.
1039 if (!m_matchStyle && !enclosingList(insertionPos.containerNode())) { 1039 if (!m_matchStyle && !enclosingList(insertionPos.containerNode())) {
1040 if (insertionPos.containerNode()->isTextNode() && insertionPos.offsetInC ontainerNode() && !insertionPos.atLastEditingPositionForNode()) { 1040 if (insertionPos.containerNode()->isTextNode() && insertionPos.offsetInC ontainerNode() && !insertionPos.atLastEditingPositionForNode()) {
1041 splitTextNode(insertionPos.containerText(), insertionPos.offsetInCon tainerNode()); 1041 splitTextNode(insertionPos.containerText(), insertionPos.offsetInCon tainerNode());
1042 insertionPos = firstPositionInNode(insertionPos.containerNode()); 1042 insertionPos = firstPositionInNode(insertionPos.containerNode());
1043 } 1043 }
1044 1044
1045 if (RefPtr<Node> nodeToSplitTo = nodeToSplitToAvoidPastingIntoInlineNode sWithStyle(insertionPos)) { 1045 if (RefPtrWillBeRawPtr<Node> nodeToSplitTo = nodeToSplitToAvoidPastingIn toInlineNodesWithStyle(insertionPos)) {
1046 if (insertionPos.containerNode() != nodeToSplitTo->parentNode()) { 1046 if (insertionPos.containerNode() != nodeToSplitTo->parentNode()) {
1047 Node* splitStart = insertionPos.computeNodeAfterPosition(); 1047 Node* splitStart = insertionPos.computeNodeAfterPosition();
1048 if (!splitStart) 1048 if (!splitStart)
1049 splitStart = insertionPos.containerNode(); 1049 splitStart = insertionPos.containerNode();
1050 nodeToSplitTo = splitTreeToNode(splitStart, nodeToSplitTo->paren tNode()).get(); 1050 nodeToSplitTo = splitTreeToNode(splitStart, nodeToSplitTo->paren tNode()).get();
1051 insertionPos = positionInParentBeforeNode(*nodeToSplitTo); 1051 insertionPos = positionInParentBeforeNode(*nodeToSplitTo);
1052 } 1052 }
1053 } 1053 }
1054 } 1054 }
1055 1055
1056 // FIXME: When pasting rich content we're often prevented from heading down the fast path by style spans. Try 1056 // FIXME: When pasting rich content we're often prevented from heading down the fast path by style spans. Try
1057 // again here if they've been removed. 1057 // again here if they've been removed.
1058 1058
1059 // 1) Insert the content. 1059 // 1) Insert the content.
1060 // 2) Remove redundant styles and style tags, this inner <b> for example: <b >foo <b>bar</b> baz</b>. 1060 // 2) Remove redundant styles and style tags, this inner <b> for example: <b >foo <b>bar</b> baz</b>.
1061 // 3) Merge the start of the added content with the content before the posit ion being pasted into. 1061 // 3) Merge the start of the added content with the content before the posit ion being pasted into.
1062 // 4) Do one of the following: a) expand the last br if the fragment ends wi th one and it collapsed, 1062 // 4) Do one of the following: a) expand the last br if the fragment ends wi th one and it collapsed,
1063 // b) merge the last paragraph of the incoming fragment with the paragraph t hat contained the 1063 // b) merge the last paragraph of the incoming fragment with the paragraph t hat contained the
1064 // end of the selection that was pasted into, or c) handle an interchange ne wline at the end of the 1064 // end of the selection that was pasted into, or c) handle an interchange ne wline at the end of the
1065 // incoming fragment. 1065 // incoming fragment.
1066 // 5) Add spaces for smart replace. 1066 // 5) Add spaces for smart replace.
1067 // 6) Select the replacement if requested, and match style if requested. 1067 // 6) Select the replacement if requested, and match style if requested.
1068 1068
1069 InsertedNodes insertedNodes; 1069 InsertedNodes insertedNodes;
1070 RefPtr<Node> refNode = fragment.firstChild(); 1070 RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild();
1071 ASSERT(refNode); 1071 ASSERT(refNode);
1072 RefPtr<Node> node = refNode->nextSibling(); 1072 RefPtrWillBeRawPtr<Node> node = refNode->nextSibling();
1073 1073
1074 fragment.removeNode(refNode); 1074 fragment.removeNode(refNode);
1075 1075
1076 Node* blockStart = enclosingBlock(insertionPos.deprecatedNode()); 1076 Node* blockStart = enclosingBlock(insertionPos.deprecatedNode());
1077 if ((isListElement(refNode.get()) || (isLegacyAppleStyleSpan(refNode.get()) && isListElement(refNode->firstChild()))) 1077 if ((isListElement(refNode.get()) || (isLegacyAppleStyleSpan(refNode.get()) && isListElement(refNode->firstChild())))
1078 && blockStart && blockStart->renderer()->isListItem()) 1078 && blockStart && blockStart->renderer()->isListItem())
1079 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio nPos, insertedNodes); 1079 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio nPos, insertedNodes);
1080 else { 1080 else {
1081 insertNodeAt(refNode, insertionPos); 1081 insertNodeAt(refNode, insertionPos);
1082 insertedNodes.respondToNodeInsertion(*refNode); 1082 insertedNodes.respondToNodeInsertion(*refNode);
1083 } 1083 }
1084 1084
1085 // Mutation events (bug 22634) may have already removed the inserted content 1085 // Mutation events (bug 22634) may have already removed the inserted content
1086 if (!refNode->inDocument()) 1086 if (!refNode->inDocument())
1087 return; 1087 return;
1088 1088
1089 bool plainTextFragment = isPlainTextMarkup(refNode.get()); 1089 bool plainTextFragment = isPlainTextMarkup(refNode.get());
1090 1090
1091 while (node) { 1091 while (node) {
1092 RefPtr<Node> next = node->nextSibling(); 1092 RefPtrWillBeRawPtr<Node> next = node->nextSibling();
1093 fragment.removeNode(node.get()); 1093 fragment.removeNode(node.get());
1094 insertNodeAfter(node, refNode); 1094 insertNodeAfter(node, refNode);
1095 insertedNodes.respondToNodeInsertion(*node); 1095 insertedNodes.respondToNodeInsertion(*node);
1096 1096
1097 // Mutation events (bug 22634) may have already removed the inserted con tent 1097 // Mutation events (bug 22634) may have already removed the inserted con tent
1098 if (!node->inDocument()) 1098 if (!node->inDocument())
1099 return; 1099 return;
1100 1100
1101 refNode = node; 1101 refNode = node;
1102 if (node && plainTextFragment) 1102 if (node && plainTextFragment)
(...skipping 16 matching lines...) Expand all
1119 insertionBlock = nullptr; 1119 insertionBlock = nullptr;
1120 1120
1121 VisiblePosition startOfInsertedContent(firstPositionInOrBeforeNode(insertedN odes.firstNodeInserted())); 1121 VisiblePosition startOfInsertedContent(firstPositionInOrBeforeNode(insertedN odes.firstNodeInserted()));
1122 1122
1123 // We inserted before the insertionBlock to prevent nesting, and the content before the insertionBlock wasn't in its own block and 1123 // We inserted before the insertionBlock to prevent nesting, and the content before the insertionBlock wasn't in its own block and
1124 // didn't have a br after it, so the inserted content ended up in the same p aragraph. 1124 // didn't have a br after it, so the inserted content ended up in the same p aragraph.
1125 if (!startOfInsertedContent.isNull() && insertionBlock && insertionPos.depre catedNode() == insertionBlock->parentNode() && (unsigned)insertionPos.deprecated EditingOffset() < insertionBlock->nodeIndex() && !isStartOfParagraph(startOfInse rtedContent)) 1125 if (!startOfInsertedContent.isNull() && insertionBlock && insertionPos.depre catedNode() == insertionBlock->parentNode() && (unsigned)insertionPos.deprecated EditingOffset() < insertionBlock->nodeIndex() && !isStartOfParagraph(startOfInse rtedContent))
1126 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten t.deepEquivalent()); 1126 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten t.deepEquivalent());
1127 1127
1128 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)) )) { 1128 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)) )) {
1129 RefPtr<Node> parent = endBR->parentNode(); 1129 RefPtrWillBeRawPtr<Node> parent = endBR->parentNode();
1130 insertedNodes.willRemoveNode(*endBR); 1130 insertedNodes.willRemoveNode(*endBR);
1131 removeNode(endBR); 1131 removeNode(endBR);
1132 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) { 1132 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) {
1133 insertedNodes.willRemoveNode(*nodeToRemove); 1133 insertedNodes.willRemoveNode(*nodeToRemove);
1134 removeNode(nodeToRemove); 1134 removeNode(nodeToRemove);
1135 } 1135 }
1136 } 1136 }
1137 1137
1138 makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes); 1138 makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes);
1139 1139
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 Position lastPositionToSelect; 1186 Position lastPositionToSelect;
1187 if (fragment.hasInterchangeNewlineAtEnd()) { 1187 if (fragment.hasInterchangeNewlineAtEnd()) {
1188 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); 1188 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
1189 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBound ary); 1189 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBound ary);
1190 1190
1191 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont ent) || next.isNull()) { 1191 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont ent) || next.isNull()) {
1192 if (!isStartOfParagraph(endOfInsertedContent)) { 1192 if (!isStartOfParagraph(endOfInsertedContent)) {
1193 setEndingSelection(endOfInsertedContent); 1193 setEndingSelection(endOfInsertedContent);
1194 Node* enclosingNode = enclosingBlock(endOfInsertedContent.deepEq uivalent().deprecatedNode()); 1194 Node* enclosingNode = enclosingBlock(endOfInsertedContent.deepEq uivalent().deprecatedNode());
1195 if (isListItem(enclosingNode)) { 1195 if (isListItem(enclosingNode)) {
1196 RefPtr<Node> newListItem = createListItemElement(document()) ; 1196 RefPtrWillBeRawPtr<Node> newListItem = createListItemElement (document());
1197 insertNodeAfter(newListItem, enclosingNode); 1197 insertNodeAfter(newListItem, enclosingNode);
1198 setEndingSelection(VisiblePosition(firstPositionInNode(newLi stItem.get()))); 1198 setEndingSelection(VisiblePosition(firstPositionInNode(newLi stItem.get())));
1199 } else { 1199 } else {
1200 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph 1200 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph
1201 // block's style seems to annoy users. 1201 // block's style seems to annoy users.
1202 insertParagraphSeparator(true, !startIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(), 1202 insertParagraphSeparator(true, !startIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(),
1203 isMailBlockquote, CannotCrossEditingBoundary, insertedNo des.firstNodeInserted()->parentNode())); 1203 isMailBlockquote, CannotCrossEditingBoundary, insertedNo des.firstNodeInserted()->parentNode()));
1204 } 1204 }
1205 1205
1206 // Select up to the paragraph separator that was added. 1206 // Select up to the paragraph separator that was added.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 } 1280 }
1281 1281
1282 bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) && !isChar acterSmartReplaceExemptConsideringNonBreakingSpace(endOfInsertedContent.characte rAfter(), false); 1282 bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) && !isChar acterSmartReplaceExemptConsideringNonBreakingSpace(endOfInsertedContent.characte rAfter(), false);
1283 if (needsTrailingSpace && endNode) { 1283 if (needsTrailingSpace && endNode) {
1284 bool collapseWhiteSpace = !endNode->renderer() || endNode->renderer()->s tyle()->collapseWhiteSpace(); 1284 bool collapseWhiteSpace = !endNode->renderer() || endNode->renderer()->s tyle()->collapseWhiteSpace();
1285 if (endNode->isTextNode()) { 1285 if (endNode->isTextNode()) {
1286 insertTextIntoNode(toText(endNode), endOffset, collapseWhiteSpace ? nonBreakingSpaceString() : " "); 1286 insertTextIntoNode(toText(endNode), endOffset, collapseWhiteSpace ? nonBreakingSpaceString() : " ");
1287 if (m_endOfInsertedContent.containerNode() == endNode) 1287 if (m_endOfInsertedContent.containerNode() == endNode)
1288 m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offse tInContainerNode() + 1); 1288 m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offse tInContainerNode() + 1);
1289 } else { 1289 } else {
1290 RefPtr<Node> node = document().createEditingTextNode(collapseWhiteSp ace ? nonBreakingSpaceString() : " "); 1290 RefPtrWillBeRawPtr<Node> node = document().createEditingTextNode(col lapseWhiteSpace ? nonBreakingSpaceString() : " ");
1291 insertNodeAfter(node, endNode); 1291 insertNodeAfter(node, endNode);
1292 updateNodesInserted(node.get()); 1292 updateNodesInserted(node.get());
1293 } 1293 }
1294 } 1294 }
1295 1295
1296 document().updateLayout(); 1296 document().updateLayout();
1297 1297
1298 Position startDownstream = startOfInsertedContent.deepEquivalent().downstrea m(); 1298 Position startDownstream = startOfInsertedContent.deepEquivalent().downstrea m();
1299 Node* startNode = startDownstream.computeNodeAfterPosition(); 1299 Node* startNode = startDownstream.computeNodeAfterPosition();
1300 unsigned startOffset = 0; 1300 unsigned startOffset = 0;
1301 if (startDownstream.anchorType() == Position::PositionIsOffsetInAnchor) { 1301 if (startDownstream.anchorType() == Position::PositionIsOffsetInAnchor) {
1302 startNode = startDownstream.containerNode(); 1302 startNode = startDownstream.containerNode();
1303 startOffset = startDownstream.offsetInContainerNode(); 1303 startOffset = startDownstream.offsetInContainerNode();
1304 } 1304 }
1305 1305
1306 bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) && !isC haracterSmartReplaceExemptConsideringNonBreakingSpace(startOfInsertedContent.pre vious().characterAfter(), true); 1306 bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) && !isC haracterSmartReplaceExemptConsideringNonBreakingSpace(startOfInsertedContent.pre vious().characterAfter(), true);
1307 if (needsLeadingSpace && startNode) { 1307 if (needsLeadingSpace && startNode) {
1308 bool collapseWhiteSpace = !startNode->renderer() || startNode->renderer( )->style()->collapseWhiteSpace(); 1308 bool collapseWhiteSpace = !startNode->renderer() || startNode->renderer( )->style()->collapseWhiteSpace();
1309 if (startNode->isTextNode()) { 1309 if (startNode->isTextNode()) {
1310 insertTextIntoNode(toText(startNode), startOffset, collapseWhiteSpac e ? nonBreakingSpaceString() : " "); 1310 insertTextIntoNode(toText(startNode), startOffset, collapseWhiteSpac e ? nonBreakingSpaceString() : " ");
1311 if (m_endOfInsertedContent.containerNode() == startNode && m_endOfIn sertedContent.offsetInContainerNode()) 1311 if (m_endOfInsertedContent.containerNode() == startNode && m_endOfIn sertedContent.offsetInContainerNode())
1312 m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offse tInContainerNode() + 1); 1312 m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offse tInContainerNode() + 1);
1313 } else { 1313 } else {
1314 RefPtr<Node> node = document().createEditingTextNode(collapseWhiteSp ace ? nonBreakingSpaceString() : " "); 1314 RefPtrWillBeRawPtr<Node> node = document().createEditingTextNode(col lapseWhiteSpace ? nonBreakingSpaceString() : " ");
1315 // Don't updateNodesInserted. Doing so would set m_endOfInsertedCont ent to be the node containing the leading space, 1315 // Don't updateNodesInserted. Doing so would set m_endOfInsertedCont ent to be the node containing the leading space,
1316 // but m_endOfInsertedContent is supposed to mark the end of pasted content. 1316 // but m_endOfInsertedContent is supposed to mark the end of pasted content.
1317 insertNodeBefore(node, startNode); 1317 insertNodeBefore(node, startNode);
1318 m_startOfInsertedContent = firstPositionInNode(node.get()); 1318 m_startOfInsertedContent = firstPositionInNode(node.get());
1319 } 1319 }
1320 } 1320 }
1321 } 1321 }
1322 1322
1323 void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi onToSelect) 1323 void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi onToSelect)
1324 { 1324 {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 1429
1430 // If we're in the middle of a list item, we should split it into two separa te 1430 // If we're in the middle of a list item, we should split it into two separa te
1431 // list items and insert these nodes between them. 1431 // list items and insert these nodes between them.
1432 if (isMiddle) { 1432 if (isMiddle) {
1433 int textNodeOffset = insertPos.offsetInContainerNode(); 1433 int textNodeOffset = insertPos.offsetInContainerNode();
1434 if (insertPos.deprecatedNode()->isTextNode() && textNodeOffset > 0) 1434 if (insertPos.deprecatedNode()->isTextNode() && textNodeOffset > 0)
1435 splitTextNode(toText(insertPos.deprecatedNode()), textNodeOffset); 1435 splitTextNode(toText(insertPos.deprecatedNode()), textNodeOffset);
1436 splitTreeToNode(insertPos.deprecatedNode(), lastNode, true); 1436 splitTreeToNode(insertPos.deprecatedNode(), lastNode, true);
1437 } 1437 }
1438 1438
1439 while (RefPtr<Node> listItem = listElement->firstChild()) { 1439 while (RefPtrWillBeRawPtr<Node> listItem = listElement->firstChild()) {
1440 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION); 1440 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION);
1441 if (isStart || isMiddle) { 1441 if (isStart || isMiddle) {
1442 insertNodeBefore(listItem, lastNode); 1442 insertNodeBefore(listItem, lastNode);
1443 insertedNodes.respondToNodeInsertion(*listItem); 1443 insertedNodes.respondToNodeInsertion(*listItem);
1444 } else if (isEnd) { 1444 } else if (isEnd) {
1445 insertNodeAfter(listItem, lastNode); 1445 insertNodeAfter(listItem, lastNode);
1446 insertedNodes.respondToNodeInsertion(*listItem); 1446 insertedNodes.respondToNodeInsertion(*listItem);
1447 lastNode = listItem.get(); 1447 lastNode = listItem.get();
1448 } else 1448 } else
1449 ASSERT_NOT_REACHED(); 1449 ASSERT_NOT_REACHED();
(...skipping 26 matching lines...) Expand all
1476 return false; 1476 return false;
1477 1477
1478 // FIXME: Would be nice to handle smart replace in the fast path. 1478 // FIXME: Would be nice to handle smart replace in the fast path.
1479 if (m_smartReplace || fragment.hasInterchangeNewlineAtStart() || fragment.ha sInterchangeNewlineAtEnd()) 1479 if (m_smartReplace || fragment.hasInterchangeNewlineAtStart() || fragment.ha sInterchangeNewlineAtEnd())
1480 return false; 1480 return false;
1481 1481
1482 // e.g. when "bar" is inserted after "foo" in <div><u>foo</u></div>, "bar" s hould not be underlined. 1482 // e.g. when "bar" is inserted after "foo" in <div><u>foo</u></div>, "bar" s hould not be underlined.
1483 if (nodeToSplitToAvoidPastingIntoInlineNodesWithStyle(endingSelection().star t())) 1483 if (nodeToSplitToAvoidPastingIntoInlineNodesWithStyle(endingSelection().star t()))
1484 return false; 1484 return false;
1485 1485
1486 RefPtr<Node> nodeAfterInsertionPos = endingSelection().end().downstream().an chorNode(); 1486 RefPtrWillBeRawPtr<Node> nodeAfterInsertionPos = endingSelection().end().dow nstream().anchorNode();
1487 Text* textNode = toText(fragment.firstChild()); 1487 Text* textNode = toText(fragment.firstChild());
1488 // Our fragment creation code handles tabs, spaces, and newlines, so we don' t have to worry about those here. 1488 // Our fragment creation code handles tabs, spaces, and newlines, so we don' t have to worry about those here.
1489 1489
1490 Position start = endingSelection().start(); 1490 Position start = endingSelection().start();
1491 Position end = replaceSelectedTextInNode(textNode->data()); 1491 Position end = replaceSelectedTextInNode(textNode->data());
1492 if (end.isNull()) 1492 if (end.isNull())
1493 return false; 1493 return false;
1494 1494
1495 if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBR Element(*nodeAfterInsertionPos) 1495 if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBR Element(*nodeAfterInsertionPos)
1496 && shouldRemoveEndBR(nodeAfterInsertionPos.get(), VisiblePosition(positi onBeforeNode(nodeAfterInsertionPos.get())))) 1496 && shouldRemoveEndBR(nodeAfterInsertionPos.get(), VisiblePosition(positi onBeforeNode(nodeAfterInsertionPos.get()))))
1497 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); 1497 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get());
1498 1498
1499 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en d); 1499 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en d);
1500 1500
1501 setEndingSelection(selectionAfterReplace); 1501 setEndingSelection(selectionAfterReplace);
1502 1502
1503 return true; 1503 return true;
1504 } 1504 }
1505 1505
1506 void ReplaceSelectionCommand::trace(Visitor* visitor)
1507 {
1508 visitor->trace(m_insertionStyle);
1509 visitor->trace(m_documentFragment);
1510 CompositeEditCommand::trace(visitor);
1511 }
1512
1506 } // namespace WebCore 1513 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698