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

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

Issue 299353004: Oilpan: move editing objects to the heap. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased + tidied Created 6 years, 6 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) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved.
4 * Copyright (C) 2011 Igalia S.L. 4 * Copyright (C) 2011 Igalia S.L.
5 * Copyright (C) 2011 Motorola Mobility. All rights reserved. 5 * Copyright (C) 2011 Motorola Mobility. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 #include "wtf/text/StringBuilder.h" 61 #include "wtf/text/StringBuilder.h"
62 62
63 using namespace std; 63 using namespace std;
64 64
65 namespace WebCore { 65 namespace WebCore {
66 66
67 using namespace HTMLNames; 67 using namespace HTMLNames;
68 68
69 static bool propertyMissingOrEqualToNone(StylePropertySet*, CSSPropertyID); 69 static bool propertyMissingOrEqualToNone(StylePropertySet*, CSSPropertyID);
70 70
71 class AttributeChange { 71 class AttributeChange : public NoBaseWillBeGarbageCollectedFinalized<AttributeCh ange> {
72 public: 72 public:
73 AttributeChange() 73 static PassOwnPtrWillBeRawPtr<AttributeChange> create(PassRefPtrWillBeRawPtr <Element> element, const QualifiedName& name, const String& value)
74 : m_name(nullAtom, nullAtom, nullAtom)
75 { 74 {
75 return adoptPtrWillBeNoop(new AttributeChange(element, name, value));
76 } 76 }
77 77
78 AttributeChange(PassRefPtr<Element> element, const QualifiedName& name, cons t String& value) 78 AttributeChange(PassRefPtrWillBeRawPtr<Element> element, const QualifiedName & name, const String& value)
79 : m_element(element), m_name(name), m_value(value) 79 : m_element(element), m_name(name), m_value(value)
80 { 80 {
81 } 81 }
82 82
83 void apply() 83 void apply()
84 { 84 {
85 m_element->setAttribute(m_name, AtomicString(m_value)); 85 m_element->setAttribute(m_name, AtomicString(m_value));
86 } 86 }
87 87
88 void trace(Visitor* visitor)
89 {
90 visitor->trace(m_element);
91 }
92
88 private: 93 private:
89 RefPtr<Element> m_element; 94 RefPtrWillBeMember<Element> m_element;
90 QualifiedName m_name; 95 QualifiedName m_name;
91 String m_value; 96 String m_value;
92 }; 97 };
93 98
94 static void completeURLs(DocumentFragment& fragment, const String& baseURL) 99 static void completeURLs(DocumentFragment& fragment, const String& baseURL)
95 { 100 {
96 Vector<AttributeChange> changes; 101 WillBeHeapVector<OwnPtrWillBeMember<AttributeChange> > changes;
97 102
98 KURL parsedBaseURL(ParsedURLString, baseURL); 103 KURL parsedBaseURL(ParsedURLString, baseURL);
99 104
100 for (Element* element = ElementTraversal::firstWithin(fragment); element; el ement = ElementTraversal::next(*element, &fragment)) { 105 for (Element* element = ElementTraversal::firstWithin(fragment); element; el ement = ElementTraversal::next(*element, &fragment)) {
101 if (!element->hasAttributes()) 106 if (!element->hasAttributes())
102 continue; 107 continue;
103 unsigned length = element->attributeCount(); 108 unsigned length = element->attributeCount();
104 for (unsigned i = 0; i < length; i++) { 109 for (unsigned i = 0; i < length; i++) {
105 const Attribute& attribute = element->attributeItem(i); 110 const Attribute& attribute = element->attributeItem(i);
106 if (element->isURLAttribute(attribute) && !attribute.value().isEmpty ()) 111 if (element->isURLAttribute(attribute) && !attribute.value().isEmpty ())
107 changes.append(AttributeChange(element, attribute.name(), KURL(p arsedBaseURL, attribute.value()).string())); 112 changes.append(AttributeChange::create(element, attribute.name() , KURL(parsedBaseURL, attribute.value()).string()));
108 } 113 }
109 } 114 }
110 115
111 size_t numChanges = changes.size(); 116 size_t numChanges = changes.size();
112 for (size_t i = 0; i < numChanges; ++i) 117 for (size_t i = 0; i < numChanges; ++i)
113 changes[i].apply(); 118 changes[i]->apply();
114 } 119 }
115 120
116 class StyledMarkupAccumulator FINAL : public MarkupAccumulator { 121 class StyledMarkupAccumulator FINAL : public MarkupAccumulator {
117 public: 122 public:
118 enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode }; 123 enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode };
119 124
120 StyledMarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs, EAnnotateForInt erchange, const Range*, Node* highestNodeToBeSerialized = 0); 125 StyledMarkupAccumulator(WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes, EAbsoluteURLs, EAnnotateForInterchange, RawPtr<const Range>, Node* highestNodeTo BeSerialized = 0);
121 Node* serializeNodes(Node* startNode, Node* pastEnd); 126 Node* serializeNodes(Node* startNode, Node* pastEnd);
122 void appendString(const String& s) { return MarkupAccumulator::appendString( s); } 127 void appendString(const String& s) { return MarkupAccumulator::appendString( s); }
123 void wrapWithNode(Node&, bool convertBlocksToInlines = false, RangeFullySele ctsNode = DoesFullySelectNode); 128 void wrapWithNode(Node&, bool convertBlocksToInlines = false, RangeFullySele ctsNode = DoesFullySelectNode);
124 void wrapWithStyleNode(StylePropertySet*, const Document&, bool isBlock = fa lse); 129 void wrapWithStyleNode(StylePropertySet*, const Document&, bool isBlock = fa lse);
125 String takeResults(); 130 String takeResults();
126 131
127 private: 132 private:
128 void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, const Documen t&, bool isBlock = false); 133 void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, const Documen t&, bool isBlock = false);
129 const String& styleNodeCloseTag(bool isBlock = false); 134 const String& styleNodeCloseTag(bool isBlock = false);
130 virtual void appendText(StringBuilder& out, Text&) OVERRIDE; 135 virtual void appendText(StringBuilder& out, Text&) OVERRIDE;
131 String renderedText(Node&, const Range*); 136 String renderedText(Node&, const Range*);
132 String stringValueForRange(const Node&, const Range*); 137 String stringValueForRange(const Node&, const Range*);
133 void appendElement(StringBuilder& out, Element&, bool addDisplayInline, Rang eFullySelectsNode); 138 void appendElement(StringBuilder& out, Element&, bool addDisplayInline, Rang eFullySelectsNode);
134 virtual void appendElement(StringBuilder& out, Element& element, Namespaces* ) OVERRIDE { appendElement(out, element, false, DoesFullySelectNode); } 139 virtual void appendElement(StringBuilder& out, Element& element, Namespaces* ) OVERRIDE { appendElement(out, element, false, DoesFullySelectNode); }
135 140
136 enum NodeTraversalMode { EmitString, DoNotEmitString }; 141 enum NodeTraversalMode { EmitString, DoNotEmitString };
137 Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTrav ersalMode); 142 Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTrav ersalMode);
138 143
139 bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; } 144 bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; }
140 bool shouldApplyWrappingStyle(const Node& node) const 145 bool shouldApplyWrappingStyle(const Node& node) const
141 { 146 {
142 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->paren tNode() == node.parentNode() 147 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->paren tNode() == node.parentNode()
143 && m_wrappingStyle && m_wrappingStyle->style(); 148 && m_wrappingStyle && m_wrappingStyle->style();
144 } 149 }
145 150
146 Vector<String> m_reversedPrecedingMarkup; 151 Vector<String> m_reversedPrecedingMarkup;
147 const EAnnotateForInterchange m_shouldAnnotate; 152 const EAnnotateForInterchange m_shouldAnnotate;
148 Node* m_highestNodeToBeSerialized; 153 RawPtrWillBeMember<Node> m_highestNodeToBeSerialized;
149 RefPtr<EditingStyle> m_wrappingStyle; 154 RefPtrWillBeMember<EditingStyle> m_wrappingStyle;
haraken 2014/05/28 15:35:25 Who traces these Members? Ian: It'd be great if t
haraken 2014/05/29 01:14:15 Ignore this comment :) I found that this object is
150 }; 155 };
151 156
152 inline StyledMarkupAccumulator::StyledMarkupAccumulator(Vector<Node*>* nodes, EA bsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, 157 inline StyledMarkupAccumulator::StyledMarkupAccumulator(WillBeHeapVector<RawPtrW illBeMember<Node> >* nodes, EAbsoluteURLs shouldResolveURLs, EAnnotateForInterch ange shouldAnnotate, RawPtr<const Range> range, Node* highestNodeToBeSerialized)
153 const Range* range, Node* highestNodeToBeSerialized)
154 : MarkupAccumulator(nodes, shouldResolveURLs, range) 158 : MarkupAccumulator(nodes, shouldResolveURLs, range)
155 , m_shouldAnnotate(shouldAnnotate) 159 , m_shouldAnnotate(shouldAnnotate)
156 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) 160 , m_highestNodeToBeSerialized(highestNodeToBeSerialized)
157 { 161 {
158 } 162 }
159 163
160 void StyledMarkupAccumulator::wrapWithNode(Node& node, bool convertBlocksToInlin es, RangeFullySelectsNode rangeFullySelectsNode) 164 void StyledMarkupAccumulator::wrapWithNode(Node& node, bool convertBlocksToInlin es, RangeFullySelectsNode rangeFullySelectsNode)
161 { 165 {
162 StringBuilder markup; 166 StringBuilder markup;
163 if (node.isElementNode()) 167 if (node.isElementNode())
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 213
210 // We remove '\0' characters because they are not visibly rendered to the us er. 214 // We remove '\0' characters because they are not visibly rendered to the us er.
211 return result.toString().replace(0, ""); 215 return result.toString().replace(0, "");
212 } 216 }
213 217
214 void StyledMarkupAccumulator::appendText(StringBuilder& out, Text& text) 218 void StyledMarkupAccumulator::appendText(StringBuilder& out, Text& text)
215 { 219 {
216 const bool parentIsTextarea = text.parentElement() && text.parentElement()-> tagQName() == textareaTag; 220 const bool parentIsTextarea = text.parentElement() && text.parentElement()-> tagQName() == textareaTag;
217 const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextare a; 221 const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextare a;
218 if (wrappingSpan) { 222 if (wrappingSpan) {
219 RefPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy(); 223 RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy() ;
220 // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance 224 // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance
221 // Make sure spans are inline style in paste side e.g. span { display: b lock }. 225 // Make sure spans are inline style in paste side e.g. span { display: b lock }.
222 wrappingStyle->forceInline(); 226 wrappingStyle->forceInline();
223 // FIXME: Should this be included in forceInline? 227 // FIXME: Should this be included in forceInline?
224 wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone); 228 wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone);
225 229
226 appendStyleNodeOpenTag(out, wrappingStyle->style(), text.document()); 230 appendStyleNodeOpenTag(out, wrappingStyle->style(), text.document());
227 } 231 }
228 232
229 if (!shouldAnnotate() || parentIsTextarea) 233 if (!shouldAnnotate() || parentIsTextarea)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp plyWrappingStyle(element); 286 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp plyWrappingStyle(element);
283 for (unsigned i = 0; i < length; ++i) { 287 for (unsigned i = 0; i < length; ++i) {
284 const Attribute& attribute = element.attributeItem(i); 288 const Attribute& attribute = element.attributeItem(i);
285 // We'll handle the style attribute separately, below. 289 // We'll handle the style attribute separately, below.
286 if (attribute.name() == styleAttr && shouldOverrideStyleAttr) 290 if (attribute.name() == styleAttr && shouldOverrideStyleAttr)
287 continue; 291 continue;
288 appendAttribute(out, element, attribute, 0); 292 appendAttribute(out, element, attribute, 0);
289 } 293 }
290 294
291 if (shouldOverrideStyleAttr) { 295 if (shouldOverrideStyleAttr) {
292 RefPtr<EditingStyle> newInlineStyle; 296 RefPtrWillBeRawPtr<EditingStyle> newInlineStyle;
haraken 2014/05/28 15:35:25 = nullptr; Mads prefers always-initialization eve
Mads Ager (chromium) 2014/05/28 16:09:44 I do prefer that. :-) On the other hand I don't h
sof 2014/05/28 22:06:06 Complied.
293 297
294 if (shouldApplyWrappingStyle(element)) { 298 if (shouldApplyWrappingStyle(element)) {
295 newInlineStyle = m_wrappingStyle->copy(); 299 newInlineStyle = m_wrappingStyle->copy();
296 newInlineStyle->removePropertiesInElementDefaultStyle(&element); 300 newInlineStyle->removePropertiesInElementDefaultStyle(&element);
297 newInlineStyle->removeStyleConflictingWithStyleOfNode(&element); 301 newInlineStyle->removeStyleConflictingWithStyleOfNode(&element);
298 } else 302 } else
299 newInlineStyle = EditingStyle::create(); 303 newInlineStyle = EditingStyle::create();
300 304
301 if (element.isStyledElement() && element.inlineStyle()) 305 if (element.isStyledElement() && element.inlineStyle())
302 newInlineStyle->overrideWithStyle(element.inlineStyle()); 306 newInlineStyle->overrideWithStyle(element.inlineStyle());
(...skipping 30 matching lines...) Expand all
333 337
334 if (m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode() ) 338 if (m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode() )
335 m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(m_highestN odeToBeSerialized->parentNode(), shouldAnnotate()); 339 m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(m_highestN odeToBeSerialized->parentNode(), shouldAnnotate());
336 340
337 return traverseNodesForSerialization(startNode, pastEnd, EmitString); 341 return traverseNodesForSerialization(startNode, pastEnd, EmitString);
338 } 342 }
339 343
340 Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No de* pastEnd, NodeTraversalMode traversalMode) 344 Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No de* pastEnd, NodeTraversalMode traversalMode)
341 { 345 {
342 const bool shouldEmit = traversalMode == EmitString; 346 const bool shouldEmit = traversalMode == EmitString;
343 Vector<Node*> ancestorsToClose; 347 WillBeHeapVector<RawPtrWillBeMember<Node> > ancestorsToClose;
344 Node* next; 348 Node* next;
345 Node* lastClosed = 0; 349 Node* lastClosed = 0;
346 for (Node* n = startNode; n != pastEnd; n = next) { 350 for (Node* n = startNode; n != pastEnd; n = next) {
347 // According to <rdar://problem/5730668>, it is possible for n to blow 351 // According to <rdar://problem/5730668>, it is possible for n to blow
348 // past pastEnd and become null here. This shouldn't be possible. 352 // past pastEnd and become null here. This shouldn't be possible.
349 // This null check will prevent crashes (but create too much markup) 353 // This null check will prevent crashes (but create too much markup)
350 // and the ASSERT will hopefully lead us to understanding the problem. 354 // and the ASSERT will hopefully lead us to understanding the problem.
351 ASSERT(n); 355 ASSERT(n);
352 if (!n) 356 if (!n)
353 break; 357 break;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 472
469 static bool needInterchangeNewlineAfter(const VisiblePosition& v) 473 static bool needInterchangeNewlineAfter(const VisiblePosition& v)
470 { 474 {
471 VisiblePosition next = v.next(); 475 VisiblePosition next = v.next();
472 Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode(); 476 Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode();
473 Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode(); 477 Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode();
474 // Add an interchange newline if a paragraph break is selected and a br won' t already be added to the markup to represent it. 478 // Add an interchange newline if a paragraph break is selected and a br won' t already be added to the markup to represent it.
475 return isEndOfParagraph(v) && isStartOfParagraph(next) && !(isHTMLBRElement( *upstreamNode) && upstreamNode == downstreamNode); 479 return isEndOfParagraph(v) && isStartOfParagraph(next) && !(isHTMLBRElement( *upstreamNode) && upstreamNode == downstreamNode);
476 } 480 }
477 481
478 static PassRefPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* n ode) 482 static PassRefPtrWillBeRawPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(c onst Node* node)
479 { 483 {
480 if (!node->isHTMLElement()) 484 if (!node->isHTMLElement())
481 return nullptr; 485 return nullptr;
482 486
483 // FIXME: Having to const_cast here is ugly, but it is quite a bit of work t o untangle 487 // FIXME: Having to const_cast here is ugly, but it is quite a bit of work t o untangle
484 // the non-const-ness of styleFromMatchedRulesForElement. 488 // the non-const-ness of styleFromMatchedRulesForElement.
485 HTMLElement* element = const_cast<HTMLElement*>(toHTMLElement(node)); 489 HTMLElement* element = const_cast<HTMLElement*>(toHTMLElement(node));
486 RefPtr<EditingStyle> style = EditingStyle::create(element->inlineStyle()); 490 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(element->inlin eStyle());
487 style->mergeStyleFromRules(element); 491 style->mergeStyleFromRules(element);
488 return style.release(); 492 return style.release();
489 } 493 }
490 494
491 static bool isElementPresentational(const Node* node) 495 static bool isElementPresentational(const Node* node)
492 { 496 {
493 return node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName( strikeTag) 497 return node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName( strikeTag)
494 || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName (bTag) || node->hasTagName(strongTag); 498 || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName (bTag) || node->hasTagName(strongTag);
495 } 499 }
496 500
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 specialCommonAncestor = commonAncestor; 538 specialCommonAncestor = commonAncestor;
535 539
536 if (Node *enclosingAnchor = enclosingNodeWithTag(firstPositionInNode(special CommonAncestor ? specialCommonAncestor : commonAncestor), aTag)) 540 if (Node *enclosingAnchor = enclosingNodeWithTag(firstPositionInNode(special CommonAncestor ? specialCommonAncestor : commonAncestor), aTag))
537 specialCommonAncestor = enclosingAnchor; 541 specialCommonAncestor = enclosingAnchor;
538 542
539 return specialCommonAncestor; 543 return specialCommonAncestor;
540 } 544 }
541 545
542 // FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForIntercha nge? 546 // FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForIntercha nge?
543 // FIXME: At least, annotation and style info should probably not be included in range.markupString() 547 // FIXME: At least, annotation and style info should probably not be included in range.markupString()
544 static String createMarkupInternal(Document& document, const Range* range, const Range* updatedRange, Vector<Node*>* nodes, 548 static String createMarkupInternal(Document& document, const Range* range, const Range* updatedRange, WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes,
545 EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsolu teURLs shouldResolveURLs, Node* constrainingAncestor) 549 EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsolu teURLs shouldResolveURLs, Node* constrainingAncestor)
546 { 550 {
547 ASSERT(range); 551 ASSERT(range);
548 ASSERT(updatedRange); 552 ASSERT(updatedRange);
549 DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, ("<br class=\"" AppleInterchangeNewline "\">")); 553 DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, ("<br class=\"" AppleInterchangeNewline "\">"));
550 554
551 bool collapsed = updatedRange->collapsed(); 555 bool collapsed = updatedRange->collapsed();
552 if (collapsed) 556 if (collapsed)
553 return emptyString(); 557 return emptyString();
554 Node* commonAncestor = updatedRange->commonAncestorContainer(); 558 Node* commonAncestor = updatedRange->commonAncestorContainer();
(...skipping 24 matching lines...) Expand all
579 if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0, AS SERT_NO_EXCEPTION) >= 0) 583 if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0, AS SERT_NO_EXCEPTION) >= 0)
580 return interchangeNewlineString; 584 return interchangeNewlineString;
581 } 585 }
582 586
583 Node* lastClosed = accumulator.serializeNodes(startNode, pastEnd); 587 Node* lastClosed = accumulator.serializeNodes(startNode, pastEnd);
584 588
585 if (specialCommonAncestor && lastClosed) { 589 if (specialCommonAncestor && lastClosed) {
586 // Also include all of the ancestors of lastClosed up to this special an cestor. 590 // Also include all of the ancestors of lastClosed up to this special an cestor.
587 for (ContainerNode* ancestor = lastClosed->parentNode(); ancestor; ances tor = ancestor->parentNode()) { 591 for (ContainerNode* ancestor = lastClosed->parentNode(); ancestor; ances tor = ancestor->parentNode()) {
588 if (ancestor == fullySelectedRoot && !convertBlocksToInlines) { 592 if (ancestor == fullySelectedRoot && !convertBlocksToInlines) {
589 RefPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRu lesAndInlineDecl(fullySelectedRoot); 593 RefPtrWillBeRawPtr<EditingStyle> fullySelectedRootStyle = styleF romMatchedRulesAndInlineDecl(fullySelectedRoot);
590 594
591 // Bring the background attribute over, but not as an attribute because a background attribute on a div 595 // Bring the background attribute over, but not as an attribute because a background attribute on a div
592 // appears to have no effect. 596 // appears to have no effect.
593 if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundI mage)) 597 if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundI mage))
594 && toElement(fullySelectedRoot)->hasAttribute(backgroundAttr )) 598 && toElement(fullySelectedRoot)->hasAttribute(backgroundAttr ))
595 fullySelectedRootStyle->style()->setProperty(CSSPropertyBack groundImage, "url('" + toElement(fullySelectedRoot)->getAttribute(backgroundAttr ) + "')"); 599 fullySelectedRootStyle->style()->setProperty(CSSPropertyBack groundImage, "url('" + toElement(fullySelectedRoot)->getAttribute(backgroundAttr ) + "')");
596 600
597 if (fullySelectedRootStyle->style()) { 601 if (fullySelectedRootStyle->style()) {
598 // Reset the CSS properties to avoid an assertion error in a ddStyleMarkup(). 602 // Reset the CSS properties to avoid an assertion error in a ddStyleMarkup().
599 // This assertion is caused at least when we select all text of a <body> element whose 603 // This assertion is caused at least when we select all text of a <body> element whose
(...skipping 17 matching lines...) Expand all
617 } 621 }
618 } 622 }
619 623
620 // FIXME: The interchange newline should be placed in the block that it's in , not after all of the content, unconditionally. 624 // FIXME: The interchange newline should be placed in the block that it's in , not after all of the content, unconditionally.
621 if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter( visibleEnd.previous())) 625 if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter( visibleEnd.previous()))
622 accumulator.appendString(interchangeNewlineString); 626 accumulator.appendString(interchangeNewlineString);
623 627
624 return accumulator.takeResults(); 628 return accumulator.takeResults();
625 } 629 }
626 630
627 String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc hange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveUR Ls, Node* constrainingAncestor) 631 String createMarkup(const Range* range, WillBeHeapVector<RawPtrWillBeMember<Node > >* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs, Node* constrainingAncestor)
628 { 632 {
629 if (!range) 633 if (!range)
630 return emptyString(); 634 return emptyString();
631 635
632 Document& document = range->ownerDocument(); 636 Document& document = range->ownerDocument();
633 const Range* updatedRange = range; 637 const Range* updatedRange = range;
634 638
635 return createMarkupInternal(document, range, updatedRange, nodes, shouldAnno tate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor); 639 return createMarkupInternal(document, range, updatedRange, nodes, shouldAnno tate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor);
636 } 640 }
637 641
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 if (specialCommonAncestor) 731 if (specialCommonAncestor)
728 fragment->appendChild(specialCommonAncestor); 732 fragment->appendChild(specialCommonAncestor);
729 else 733 else
730 fragment->parserTakeAllChildrenFrom(toContainerNode(*commonAncestor)); 734 fragment->parserTakeAllChildrenFrom(toContainerNode(*commonAncestor));
731 735
732 trimFragment(fragment.get(), nodeBeforeContext.get(), nodeAfterContext.get() ); 736 trimFragment(fragment.get(), nodeBeforeContext.get(), nodeAfterContext.get() );
733 737
734 return fragment; 738 return fragment;
735 } 739 }
736 740
737 String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, Vector<QualifiedName>* tagNamesToSkip) 741 String createMarkup(const Node* node, EChildrenOnly childrenOnly, WillBeHeapVect or<RawPtrWillBeMember<Node> >* nodes, EAbsoluteURLs shouldResolveURLs, Vector<Qu alifiedName>* tagNamesToSkip)
738 { 742 {
739 if (!node) 743 if (!node)
740 return ""; 744 return "";
741 745
742 MarkupAccumulator accumulator(nodes, shouldResolveURLs); 746 MarkupAccumulator accumulator(nodes, shouldResolveURLs);
743 return accumulator.serializeNodes(const_cast<Node&>(*node), childrenOnly, ta gNamesToSkip); 747 return accumulator.serializeNodes(const_cast<Node&>(*node), childrenOnly, ta gNamesToSkip);
744 } 748 }
745 749
746 static void fillContainerFromString(ContainerNode* paragraph, const String& stri ng) 750 static void fillContainerFromString(ContainerNode* paragraph, const String& stri ng)
747 { 751 {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 if (text.isEmpty()) 829 if (text.isEmpty())
826 return fragment.release(); 830 return fragment.release();
827 831
828 String string = text; 832 String string = text;
829 string.replace("\r\n", "\n"); 833 string.replace("\r\n", "\n");
830 string.replace('\r', '\n'); 834 string.replace('\r', '\n');
831 835
832 if (shouldPreserveNewline(*context)) { 836 if (shouldPreserveNewline(*context)) {
833 fragment->appendChild(document.createTextNode(string)); 837 fragment->appendChild(document.createTextNode(string));
834 if (string.endsWith('\n')) { 838 if (string.endsWith('\n')) {
835 RefPtr<Element> element = createBreakElement(document); 839 RefPtrWillBeRawPtr<Element> element = createBreakElement(document);
836 element->setAttribute(classAttr, AppleInterchangeNewline); 840 element->setAttribute(classAttr, AppleInterchangeNewline);
837 fragment->appendChild(element.release()); 841 fragment->appendChild(element.release());
838 } 842 }
839 return fragment.release(); 843 return fragment.release();
840 } 844 }
841 845
842 // A string with no newlines gets added inline, rather than being put into a paragraph. 846 // A string with no newlines gets added inline, rather than being put into a paragraph.
843 if (string.find('\n') == kNotFound) { 847 if (string.find('\n') == kNotFound) {
844 fillContainerFromString(fragment.get(), string); 848 fillContainerFromString(fragment.get(), string);
845 return fragment.release(); 849 return fragment.release();
846 } 850 }
847 851
848 // Break string into paragraphs. Extra line breaks turn into empty paragraph s. 852 // Break string into paragraphs. Extra line breaks turn into empty paragraph s.
849 Node* blockNode = enclosingBlock(context->firstNode()); 853 Node* blockNode = enclosingBlock(context->firstNode());
850 Element* block = toElement(blockNode); 854 Element* block = toElement(blockNode);
851 bool useClonesOfEnclosingBlock = blockNode 855 bool useClonesOfEnclosingBlock = blockNode
852 && blockNode->isElementNode() 856 && blockNode->isElementNode()
853 && !isHTMLBodyElement(*block) 857 && !isHTMLBodyElement(*block)
854 && !isHTMLHtmlElement(*block) 858 && !isHTMLHtmlElement(*block)
855 && block != editableRootForPosition(context->startPosition()); 859 && block != editableRootForPosition(context->startPosition());
856 bool useLineBreak = enclosingTextFormControl(context->startPosition()); 860 bool useLineBreak = enclosingTextFormControl(context->startPosition());
857 861
858 Vector<String> list; 862 Vector<String> list;
859 string.split('\n', true, list); // true gets us empty strings in the list 863 string.split('\n', true, list); // true gets us empty strings in the list
860 size_t numLines = list.size(); 864 size_t numLines = list.size();
861 for (size_t i = 0; i < numLines; ++i) { 865 for (size_t i = 0; i < numLines; ++i) {
862 const String& s = list[i]; 866 const String& s = list[i];
863 867
864 RefPtr<Element> element; 868 RefPtrWillBeRawPtr<Element> element = nullptr;
865 if (s.isEmpty() && i + 1 == numLines) { 869 if (s.isEmpty() && i + 1 == numLines) {
866 // For last line, use the "magic BR" rather than a P. 870 // For last line, use the "magic BR" rather than a P.
867 element = createBreakElement(document); 871 element = createBreakElement(document);
868 element->setAttribute(classAttr, AppleInterchangeNewline); 872 element->setAttribute(classAttr, AppleInterchangeNewline);
869 } else if (useLineBreak) { 873 } else if (useLineBreak) {
870 element = createBreakElement(document); 874 element = createBreakElement(document);
871 fillContainerFromString(fragment.get(), s); 875 fillContainerFromString(fragment.get(), s);
872 } else { 876 } else {
873 if (useClonesOfEnclosingBlock) 877 if (useClonesOfEnclosingBlock)
874 element = block->cloneElementWithoutChildren(); 878 element = block->cloneElementWithoutChildren();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 return; 1069 return;
1066 1070
1067 RefPtrWillBeRawPtr<Text> textNode = toText(node.get()); 1071 RefPtrWillBeRawPtr<Text> textNode = toText(node.get());
1068 RefPtrWillBeRawPtr<Text> textNext = toText(next); 1072 RefPtrWillBeRawPtr<Text> textNext = toText(next);
1069 textNode->appendData(textNext->data()); 1073 textNode->appendData(textNext->data());
1070 if (textNext->parentNode()) // Might have been removed by mutation event. 1074 if (textNext->parentNode()) // Might have been removed by mutation event.
1071 textNext->remove(exceptionState); 1075 textNext->remove(exceptionState);
1072 } 1076 }
1073 1077
1074 } 1078 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698