OLD | NEW |
---|---|
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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 { |
72 ALLOW_ONLY_INLINE_ALLOCATION(); | |
72 public: | 73 public: |
73 AttributeChange() | 74 AttributeChange() |
74 : m_name(nullAtom, nullAtom, nullAtom) | 75 : m_name(nullAtom, nullAtom, nullAtom) |
75 { | 76 { |
76 } | 77 } |
77 | 78 |
78 AttributeChange(PassRefPtr<Element> element, const QualifiedName& name, cons t String& value) | 79 AttributeChange(PassRefPtrWillBeRawPtr<Element> element, const QualifiedName & name, const String& value) |
79 : m_element(element), m_name(name), m_value(value) | 80 : m_element(element), m_name(name), m_value(value) |
80 { | 81 { |
81 } | 82 } |
82 | 83 |
83 void apply() | 84 void apply() |
84 { | 85 { |
85 m_element->setAttribute(m_name, AtomicString(m_value)); | 86 m_element->setAttribute(m_name, AtomicString(m_value)); |
86 } | 87 } |
87 | 88 |
89 void trace(Visitor* visitor) | |
90 { | |
91 visitor->trace(m_element); | |
92 } | |
93 | |
88 private: | 94 private: |
89 RefPtr<Element> m_element; | 95 RefPtrWillBeMember<Element> m_element; |
90 QualifiedName m_name; | 96 QualifiedName m_name; |
91 String m_value; | 97 String m_value; |
92 }; | 98 }; |
93 | 99 |
100 } // namespace WebCore | |
101 | |
102 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::AttributeChange); | |
haraken
2014/05/26 02:36:12
Is it OK to set canMoveWithMemcpy? I'm concerned t
sof
2014/05/28 08:31:35
This object needs to be on the heap and finalized
| |
103 | |
104 namespace WebCore { | |
105 | |
94 static void completeURLs(DocumentFragment& fragment, const String& baseURL) | 106 static void completeURLs(DocumentFragment& fragment, const String& baseURL) |
95 { | 107 { |
96 Vector<AttributeChange> changes; | 108 WillBeHeapVector<AttributeChange> changes; |
97 | 109 |
98 KURL parsedBaseURL(ParsedURLString, baseURL); | 110 KURL parsedBaseURL(ParsedURLString, baseURL); |
99 | 111 |
100 for (Element* element = ElementTraversal::firstWithin(fragment); element; el ement = ElementTraversal::next(*element, &fragment)) { | 112 for (Element* element = ElementTraversal::firstWithin(fragment); element; el ement = ElementTraversal::next(*element, &fragment)) { |
101 if (!element->hasAttributes()) | 113 if (!element->hasAttributes()) |
102 continue; | 114 continue; |
103 unsigned length = element->attributeCount(); | 115 unsigned length = element->attributeCount(); |
104 for (unsigned i = 0; i < length; i++) { | 116 for (unsigned i = 0; i < length; i++) { |
105 const Attribute& attribute = element->attributeItem(i); | 117 const Attribute& attribute = element->attributeItem(i); |
106 if (element->isURLAttribute(attribute) && !attribute.value().isEmpty ()) | 118 if (element->isURLAttribute(attribute) && !attribute.value().isEmpty ()) |
107 changes.append(AttributeChange(element, attribute.name(), KURL(p arsedBaseURL, attribute.value()).string())); | 119 changes.append(AttributeChange(element, attribute.name(), KURL(p arsedBaseURL, attribute.value()).string())); |
108 } | 120 } |
109 } | 121 } |
110 | 122 |
111 size_t numChanges = changes.size(); | 123 size_t numChanges = changes.size(); |
112 for (size_t i = 0; i < numChanges; ++i) | 124 for (size_t i = 0; i < numChanges; ++i) |
113 changes[i].apply(); | 125 changes[i].apply(); |
114 } | 126 } |
115 | 127 |
116 class StyledMarkupAccumulator FINAL : public MarkupAccumulator { | 128 class StyledMarkupAccumulator FINAL : public MarkupAccumulator { |
117 public: | 129 public: |
118 enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode }; | 130 enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode }; |
119 | 131 |
120 StyledMarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs, EAnnotateForInt erchange, const Range*, Node* highestNodeToBeSerialized = 0); | 132 StyledMarkupAccumulator(WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes, EAbsoluteURLs, EAnnotateForInterchange, RawPtr<const Range>, Node* highestNodeTo BeSerialized = 0); |
121 Node* serializeNodes(Node* startNode, Node* pastEnd); | 133 Node* serializeNodes(Node* startNode, Node* pastEnd); |
122 void appendString(const String& s) { return MarkupAccumulator::appendString( s); } | 134 void appendString(const String& s) { return MarkupAccumulator::appendString( s); } |
123 void wrapWithNode(Node&, bool convertBlocksToInlines = false, RangeFullySele ctsNode = DoesFullySelectNode); | 135 void wrapWithNode(Node&, bool convertBlocksToInlines = false, RangeFullySele ctsNode = DoesFullySelectNode); |
124 void wrapWithStyleNode(StylePropertySet*, const Document&, bool isBlock = fa lse); | 136 void wrapWithStyleNode(StylePropertySet*, const Document&, bool isBlock = fa lse); |
125 String takeResults(); | 137 String takeResults(); |
126 | 138 |
127 private: | 139 private: |
128 void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, const Documen t&, bool isBlock = false); | 140 void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, const Documen t&, bool isBlock = false); |
129 const String& styleNodeCloseTag(bool isBlock = false); | 141 const String& styleNodeCloseTag(bool isBlock = false); |
130 virtual void appendText(StringBuilder& out, Text&) OVERRIDE; | 142 virtual void appendText(StringBuilder& out, Text&) OVERRIDE; |
131 String renderedText(Node&, const Range*); | 143 String renderedText(Node&, const Range*); |
132 String stringValueForRange(const Node&, const Range*); | 144 String stringValueForRange(const Node&, const Range*); |
133 void appendElement(StringBuilder& out, Element&, bool addDisplayInline, Rang eFullySelectsNode); | 145 void appendElement(StringBuilder& out, Element&, bool addDisplayInline, Rang eFullySelectsNode); |
134 virtual void appendElement(StringBuilder& out, Element& element, Namespaces* ) OVERRIDE { appendElement(out, element, false, DoesFullySelectNode); } | 146 virtual void appendElement(StringBuilder& out, Element& element, Namespaces* ) OVERRIDE { appendElement(out, element, false, DoesFullySelectNode); } |
135 | 147 |
136 enum NodeTraversalMode { EmitString, DoNotEmitString }; | 148 enum NodeTraversalMode { EmitString, DoNotEmitString }; |
137 Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTrav ersalMode); | 149 Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTrav ersalMode); |
138 | 150 |
139 bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; } | 151 bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; } |
140 bool shouldApplyWrappingStyle(const Node& node) const | 152 bool shouldApplyWrappingStyle(const Node& node) const |
141 { | 153 { |
142 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->paren tNode() == node.parentNode() | 154 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->paren tNode() == node.parentNode() |
143 && m_wrappingStyle && m_wrappingStyle->style(); | 155 && m_wrappingStyle && m_wrappingStyle->style(); |
144 } | 156 } |
145 | 157 |
146 Vector<String> m_reversedPrecedingMarkup; | 158 Vector<String> m_reversedPrecedingMarkup; |
147 const EAnnotateForInterchange m_shouldAnnotate; | 159 const EAnnotateForInterchange m_shouldAnnotate; |
148 Node* m_highestNodeToBeSerialized; | 160 RawPtrWillBeMember<Node> m_highestNodeToBeSerialized; |
149 RefPtr<EditingStyle> m_wrappingStyle; | 161 RefPtrWillBeMember<EditingStyle> m_wrappingStyle; |
150 }; | 162 }; |
151 | 163 |
152 inline StyledMarkupAccumulator::StyledMarkupAccumulator(Vector<Node*>* nodes, EA bsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, | 164 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) | 165 : MarkupAccumulator(nodes, shouldResolveURLs, range) |
155 , m_shouldAnnotate(shouldAnnotate) | 166 , m_shouldAnnotate(shouldAnnotate) |
156 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) | 167 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) |
157 { | 168 { |
158 } | 169 } |
159 | 170 |
160 void StyledMarkupAccumulator::wrapWithNode(Node& node, bool convertBlocksToInlin es, RangeFullySelectsNode rangeFullySelectsNode) | 171 void StyledMarkupAccumulator::wrapWithNode(Node& node, bool convertBlocksToInlin es, RangeFullySelectsNode rangeFullySelectsNode) |
161 { | 172 { |
162 StringBuilder markup; | 173 StringBuilder markup; |
163 if (node.isElementNode()) | 174 if (node.isElementNode()) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
209 | 220 |
210 // We remove '\0' characters because they are not visibly rendered to the us er. | 221 // We remove '\0' characters because they are not visibly rendered to the us er. |
211 return result.toString().replace(0, ""); | 222 return result.toString().replace(0, ""); |
212 } | 223 } |
213 | 224 |
214 void StyledMarkupAccumulator::appendText(StringBuilder& out, Text& text) | 225 void StyledMarkupAccumulator::appendText(StringBuilder& out, Text& text) |
215 { | 226 { |
216 const bool parentIsTextarea = text.parentElement() && text.parentElement()-> tagQName() == textareaTag; | 227 const bool parentIsTextarea = text.parentElement() && text.parentElement()-> tagQName() == textareaTag; |
217 const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextare a; | 228 const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextare a; |
218 if (wrappingSpan) { | 229 if (wrappingSpan) { |
219 RefPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy(); | 230 RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy() ; |
220 // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance | 231 // 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 }. | 232 // Make sure spans are inline style in paste side e.g. span { display: b lock }. |
222 wrappingStyle->forceInline(); | 233 wrappingStyle->forceInline(); |
223 // FIXME: Should this be included in forceInline? | 234 // FIXME: Should this be included in forceInline? |
224 wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone); | 235 wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone); |
225 | 236 |
226 appendStyleNodeOpenTag(out, wrappingStyle->style(), text.document()); | 237 appendStyleNodeOpenTag(out, wrappingStyle->style(), text.document()); |
227 } | 238 } |
228 | 239 |
229 if (!shouldAnnotate() || parentIsTextarea) | 240 if (!shouldAnnotate() || parentIsTextarea) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp plyWrappingStyle(element); | 293 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp plyWrappingStyle(element); |
283 for (unsigned i = 0; i < length; ++i) { | 294 for (unsigned i = 0; i < length; ++i) { |
284 const Attribute& attribute = element.attributeItem(i); | 295 const Attribute& attribute = element.attributeItem(i); |
285 // We'll handle the style attribute separately, below. | 296 // We'll handle the style attribute separately, below. |
286 if (attribute.name() == styleAttr && shouldOverrideStyleAttr) | 297 if (attribute.name() == styleAttr && shouldOverrideStyleAttr) |
287 continue; | 298 continue; |
288 appendAttribute(out, element, attribute, 0); | 299 appendAttribute(out, element, attribute, 0); |
289 } | 300 } |
290 | 301 |
291 if (shouldOverrideStyleAttr) { | 302 if (shouldOverrideStyleAttr) { |
292 RefPtr<EditingStyle> newInlineStyle; | 303 RefPtrWillBeRawPtr<EditingStyle> newInlineStyle; |
293 | 304 |
294 if (shouldApplyWrappingStyle(element)) { | 305 if (shouldApplyWrappingStyle(element)) { |
295 newInlineStyle = m_wrappingStyle->copy(); | 306 newInlineStyle = m_wrappingStyle->copy(); |
296 newInlineStyle->removePropertiesInElementDefaultStyle(&element); | 307 newInlineStyle->removePropertiesInElementDefaultStyle(&element); |
297 newInlineStyle->removeStyleConflictingWithStyleOfNode(&element); | 308 newInlineStyle->removeStyleConflictingWithStyleOfNode(&element); |
298 } else | 309 } else |
299 newInlineStyle = EditingStyle::create(); | 310 newInlineStyle = EditingStyle::create(); |
300 | 311 |
301 if (element.isStyledElement() && element.inlineStyle()) | 312 if (element.isStyledElement() && element.inlineStyle()) |
302 newInlineStyle->overrideWithStyle(element.inlineStyle()); | 313 newInlineStyle->overrideWithStyle(element.inlineStyle()); |
(...skipping 30 matching lines...) Expand all Loading... | |
333 | 344 |
334 if (m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode() ) | 345 if (m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode() ) |
335 m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(m_highestN odeToBeSerialized->parentNode(), shouldAnnotate()); | 346 m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(m_highestN odeToBeSerialized->parentNode(), shouldAnnotate()); |
336 | 347 |
337 return traverseNodesForSerialization(startNode, pastEnd, EmitString); | 348 return traverseNodesForSerialization(startNode, pastEnd, EmitString); |
338 } | 349 } |
339 | 350 |
340 Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No de* pastEnd, NodeTraversalMode traversalMode) | 351 Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No de* pastEnd, NodeTraversalMode traversalMode) |
341 { | 352 { |
342 const bool shouldEmit = traversalMode == EmitString; | 353 const bool shouldEmit = traversalMode == EmitString; |
343 Vector<Node*> ancestorsToClose; | 354 WillBeHeapVector<RawPtrWillBeMember<Node> > ancestorsToClose; |
344 Node* next; | 355 Node* next; |
345 Node* lastClosed = 0; | 356 Node* lastClosed = 0; |
346 for (Node* n = startNode; n != pastEnd; n = next) { | 357 for (Node* n = startNode; n != pastEnd; n = next) { |
347 // According to <rdar://problem/5730668>, it is possible for n to blow | 358 // According to <rdar://problem/5730668>, it is possible for n to blow |
348 // past pastEnd and become null here. This shouldn't be possible. | 359 // past pastEnd and become null here. This shouldn't be possible. |
349 // This null check will prevent crashes (but create too much markup) | 360 // This null check will prevent crashes (but create too much markup) |
350 // and the ASSERT will hopefully lead us to understanding the problem. | 361 // and the ASSERT will hopefully lead us to understanding the problem. |
351 ASSERT(n); | 362 ASSERT(n); |
352 if (!n) | 363 if (!n) |
353 break; | 364 break; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
468 | 479 |
469 static bool needInterchangeNewlineAfter(const VisiblePosition& v) | 480 static bool needInterchangeNewlineAfter(const VisiblePosition& v) |
470 { | 481 { |
471 VisiblePosition next = v.next(); | 482 VisiblePosition next = v.next(); |
472 Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode(); | 483 Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode(); |
473 Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode(); | 484 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. | 485 // 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); | 486 return isEndOfParagraph(v) && isStartOfParagraph(next) && !(isHTMLBRElement( *upstreamNode) && upstreamNode == downstreamNode); |
476 } | 487 } |
477 | 488 |
478 static PassRefPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* n ode) | 489 static PassRefPtrWillBeRawPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(c onst Node* node) |
479 { | 490 { |
480 if (!node->isHTMLElement()) | 491 if (!node->isHTMLElement()) |
481 return nullptr; | 492 return nullptr; |
482 | 493 |
483 // FIXME: Having to const_cast here is ugly, but it is quite a bit of work t o untangle | 494 // 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. | 495 // the non-const-ness of styleFromMatchedRulesForElement. |
485 HTMLElement* element = const_cast<HTMLElement*>(toHTMLElement(node)); | 496 HTMLElement* element = const_cast<HTMLElement*>(toHTMLElement(node)); |
486 RefPtr<EditingStyle> style = EditingStyle::create(element->inlineStyle()); | 497 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(element->inlin eStyle()); |
487 style->mergeStyleFromRules(element); | 498 style->mergeStyleFromRules(element); |
488 return style.release(); | 499 return style.release(); |
489 } | 500 } |
490 | 501 |
491 static bool isElementPresentational(const Node* node) | 502 static bool isElementPresentational(const Node* node) |
492 { | 503 { |
493 return node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName( strikeTag) | 504 return node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName( strikeTag) |
494 || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName (bTag) || node->hasTagName(strongTag); | 505 || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName (bTag) || node->hasTagName(strongTag); |
495 } | 506 } |
496 | 507 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 specialCommonAncestor = commonAncestor; | 545 specialCommonAncestor = commonAncestor; |
535 | 546 |
536 if (Node *enclosingAnchor = enclosingNodeWithTag(firstPositionInNode(special CommonAncestor ? specialCommonAncestor : commonAncestor), aTag)) | 547 if (Node *enclosingAnchor = enclosingNodeWithTag(firstPositionInNode(special CommonAncestor ? specialCommonAncestor : commonAncestor), aTag)) |
537 specialCommonAncestor = enclosingAnchor; | 548 specialCommonAncestor = enclosingAnchor; |
538 | 549 |
539 return specialCommonAncestor; | 550 return specialCommonAncestor; |
540 } | 551 } |
541 | 552 |
542 // FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForIntercha nge? | 553 // 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() | 554 // 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, | 555 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) | 556 EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsolu teURLs shouldResolveURLs, Node* constrainingAncestor) |
546 { | 557 { |
547 ASSERT(range); | 558 ASSERT(range); |
548 ASSERT(updatedRange); | 559 ASSERT(updatedRange); |
549 DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, ("<br class=\"" AppleInterchangeNewline "\">")); | 560 DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, ("<br class=\"" AppleInterchangeNewline "\">")); |
550 | 561 |
551 bool collapsed = updatedRange->collapsed(); | 562 bool collapsed = updatedRange->collapsed(); |
552 if (collapsed) | 563 if (collapsed) |
553 return emptyString(); | 564 return emptyString(); |
554 Node* commonAncestor = updatedRange->commonAncestorContainer(); | 565 Node* commonAncestor = updatedRange->commonAncestorContainer(); |
(...skipping 24 matching lines...) Expand all Loading... | |
579 if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0, AS SERT_NO_EXCEPTION) >= 0) | 590 if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0, AS SERT_NO_EXCEPTION) >= 0) |
580 return interchangeNewlineString; | 591 return interchangeNewlineString; |
581 } | 592 } |
582 | 593 |
583 Node* lastClosed = accumulator.serializeNodes(startNode, pastEnd); | 594 Node* lastClosed = accumulator.serializeNodes(startNode, pastEnd); |
584 | 595 |
585 if (specialCommonAncestor && lastClosed) { | 596 if (specialCommonAncestor && lastClosed) { |
586 // Also include all of the ancestors of lastClosed up to this special an cestor. | 597 // 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()) { | 598 for (ContainerNode* ancestor = lastClosed->parentNode(); ancestor; ances tor = ancestor->parentNode()) { |
588 if (ancestor == fullySelectedRoot && !convertBlocksToInlines) { | 599 if (ancestor == fullySelectedRoot && !convertBlocksToInlines) { |
589 RefPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRu lesAndInlineDecl(fullySelectedRoot); | 600 RefPtrWillBeRawPtr<EditingStyle> fullySelectedRootStyle = styleF romMatchedRulesAndInlineDecl(fullySelectedRoot); |
590 | 601 |
591 // Bring the background attribute over, but not as an attribute because a background attribute on a div | 602 // Bring the background attribute over, but not as an attribute because a background attribute on a div |
592 // appears to have no effect. | 603 // appears to have no effect. |
593 if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundI mage)) | 604 if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundI mage)) |
594 && toElement(fullySelectedRoot)->hasAttribute(backgroundAttr )) | 605 && toElement(fullySelectedRoot)->hasAttribute(backgroundAttr )) |
595 fullySelectedRootStyle->style()->setProperty(CSSPropertyBack groundImage, "url('" + toElement(fullySelectedRoot)->getAttribute(backgroundAttr ) + "')"); | 606 fullySelectedRootStyle->style()->setProperty(CSSPropertyBack groundImage, "url('" + toElement(fullySelectedRoot)->getAttribute(backgroundAttr ) + "')"); |
596 | 607 |
597 if (fullySelectedRootStyle->style()) { | 608 if (fullySelectedRootStyle->style()) { |
598 // Reset the CSS properties to avoid an assertion error in a ddStyleMarkup(). | 609 // 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 | 610 // This assertion is caused at least when we select all text of a <body> element whose |
(...skipping 17 matching lines...) Expand all Loading... | |
617 } | 628 } |
618 } | 629 } |
619 | 630 |
620 // FIXME: The interchange newline should be placed in the block that it's in , not after all of the content, unconditionally. | 631 // 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())) | 632 if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter( visibleEnd.previous())) |
622 accumulator.appendString(interchangeNewlineString); | 633 accumulator.appendString(interchangeNewlineString); |
623 | 634 |
624 return accumulator.takeResults(); | 635 return accumulator.takeResults(); |
625 } | 636 } |
626 | 637 |
627 String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc hange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveUR Ls, Node* constrainingAncestor) | 638 String createMarkup(const Range* range, WillBeHeapVector<RawPtrWillBeMember<Node > >* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs, Node* constrainingAncestor) |
628 { | 639 { |
629 if (!range) | 640 if (!range) |
630 return emptyString(); | 641 return emptyString(); |
631 | 642 |
632 Document& document = range->ownerDocument(); | 643 Document& document = range->ownerDocument(); |
633 const Range* updatedRange = range; | 644 const Range* updatedRange = range; |
634 | 645 |
635 return createMarkupInternal(document, range, updatedRange, nodes, shouldAnno tate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor); | 646 return createMarkupInternal(document, range, updatedRange, nodes, shouldAnno tate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor); |
636 } | 647 } |
637 | 648 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
727 if (specialCommonAncestor) | 738 if (specialCommonAncestor) |
728 fragment->appendChild(specialCommonAncestor); | 739 fragment->appendChild(specialCommonAncestor); |
729 else | 740 else |
730 fragment->parserTakeAllChildrenFrom(toContainerNode(*commonAncestor)); | 741 fragment->parserTakeAllChildrenFrom(toContainerNode(*commonAncestor)); |
731 | 742 |
732 trimFragment(fragment.get(), nodeBeforeContext.get(), nodeAfterContext.get() ); | 743 trimFragment(fragment.get(), nodeBeforeContext.get(), nodeAfterContext.get() ); |
733 | 744 |
734 return fragment; | 745 return fragment; |
735 } | 746 } |
736 | 747 |
737 String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, Vector<QualifiedName>* tagNamesToSkip) | 748 String createMarkup(const Node* node, EChildrenOnly childrenOnly, WillBeHeapVect or<RawPtrWillBeMember<Node> >* nodes, EAbsoluteURLs shouldResolveURLs, Vector<Qu alifiedName>* tagNamesToSkip) |
738 { | 749 { |
739 if (!node) | 750 if (!node) |
740 return ""; | 751 return ""; |
741 | 752 |
742 MarkupAccumulator accumulator(nodes, shouldResolveURLs); | 753 MarkupAccumulator accumulator(nodes, shouldResolveURLs); |
743 return accumulator.serializeNodes(const_cast<Node&>(*node), childrenOnly, ta gNamesToSkip); | 754 return accumulator.serializeNodes(const_cast<Node&>(*node), childrenOnly, ta gNamesToSkip); |
744 } | 755 } |
745 | 756 |
746 static void fillContainerFromString(ContainerNode* paragraph, const String& stri ng) | 757 static void fillContainerFromString(ContainerNode* paragraph, const String& stri ng) |
747 { | 758 { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
825 if (text.isEmpty()) | 836 if (text.isEmpty()) |
826 return fragment.release(); | 837 return fragment.release(); |
827 | 838 |
828 String string = text; | 839 String string = text; |
829 string.replace("\r\n", "\n"); | 840 string.replace("\r\n", "\n"); |
830 string.replace('\r', '\n'); | 841 string.replace('\r', '\n'); |
831 | 842 |
832 if (shouldPreserveNewline(*context)) { | 843 if (shouldPreserveNewline(*context)) { |
833 fragment->appendChild(document.createTextNode(string)); | 844 fragment->appendChild(document.createTextNode(string)); |
834 if (string.endsWith('\n')) { | 845 if (string.endsWith('\n')) { |
835 RefPtr<Element> element = createBreakElement(document); | 846 RefPtrWillBeRawPtr<Element> element = createBreakElement(document); |
836 element->setAttribute(classAttr, AppleInterchangeNewline); | 847 element->setAttribute(classAttr, AppleInterchangeNewline); |
837 fragment->appendChild(element.release()); | 848 fragment->appendChild(element.release()); |
838 } | 849 } |
839 return fragment.release(); | 850 return fragment.release(); |
840 } | 851 } |
841 | 852 |
842 // A string with no newlines gets added inline, rather than being put into a paragraph. | 853 // A string with no newlines gets added inline, rather than being put into a paragraph. |
843 if (string.find('\n') == kNotFound) { | 854 if (string.find('\n') == kNotFound) { |
844 fillContainerFromString(fragment.get(), string); | 855 fillContainerFromString(fragment.get(), string); |
845 return fragment.release(); | 856 return fragment.release(); |
846 } | 857 } |
847 | 858 |
848 // Break string into paragraphs. Extra line breaks turn into empty paragraph s. | 859 // Break string into paragraphs. Extra line breaks turn into empty paragraph s. |
849 Node* blockNode = enclosingBlock(context->firstNode()); | 860 Node* blockNode = enclosingBlock(context->firstNode()); |
850 Element* block = toElement(blockNode); | 861 Element* block = toElement(blockNode); |
851 bool useClonesOfEnclosingBlock = blockNode | 862 bool useClonesOfEnclosingBlock = blockNode |
852 && blockNode->isElementNode() | 863 && blockNode->isElementNode() |
853 && !isHTMLBodyElement(*block) | 864 && !isHTMLBodyElement(*block) |
854 && !isHTMLHtmlElement(*block) | 865 && !isHTMLHtmlElement(*block) |
855 && block != editableRootForPosition(context->startPosition()); | 866 && block != editableRootForPosition(context->startPosition()); |
856 bool useLineBreak = enclosingTextFormControl(context->startPosition()); | 867 bool useLineBreak = enclosingTextFormControl(context->startPosition()); |
857 | 868 |
858 Vector<String> list; | 869 Vector<String> list; |
859 string.split('\n', true, list); // true gets us empty strings in the list | 870 string.split('\n', true, list); // true gets us empty strings in the list |
860 size_t numLines = list.size(); | 871 size_t numLines = list.size(); |
861 for (size_t i = 0; i < numLines; ++i) { | 872 for (size_t i = 0; i < numLines; ++i) { |
862 const String& s = list[i]; | 873 const String& s = list[i]; |
863 | 874 |
864 RefPtr<Element> element; | 875 RefPtrWillBeRawPtr<Element> element = nullptr; |
865 if (s.isEmpty() && i + 1 == numLines) { | 876 if (s.isEmpty() && i + 1 == numLines) { |
866 // For last line, use the "magic BR" rather than a P. | 877 // For last line, use the "magic BR" rather than a P. |
867 element = createBreakElement(document); | 878 element = createBreakElement(document); |
868 element->setAttribute(classAttr, AppleInterchangeNewline); | 879 element->setAttribute(classAttr, AppleInterchangeNewline); |
869 } else if (useLineBreak) { | 880 } else if (useLineBreak) { |
870 element = createBreakElement(document); | 881 element = createBreakElement(document); |
871 fillContainerFromString(fragment.get(), s); | 882 fillContainerFromString(fragment.get(), s); |
872 } else { | 883 } else { |
873 if (useClonesOfEnclosingBlock) | 884 if (useClonesOfEnclosingBlock) |
874 element = block->cloneElementWithoutChildren(); | 885 element = block->cloneElementWithoutChildren(); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1065 return; | 1076 return; |
1066 | 1077 |
1067 RefPtrWillBeRawPtr<Text> textNode = toText(node.get()); | 1078 RefPtrWillBeRawPtr<Text> textNode = toText(node.get()); |
1068 RefPtrWillBeRawPtr<Text> textNext = toText(next); | 1079 RefPtrWillBeRawPtr<Text> textNext = toText(next); |
1069 textNode->appendData(textNext->data()); | 1080 textNode->appendData(textNext->data()); |
1070 if (textNext->parentNode()) // Might have been removed by mutation event. | 1081 if (textNext->parentNode()) // Might have been removed by mutation event. |
1071 textNext->remove(exceptionState); | 1082 textNext->remove(exceptionState); |
1072 } | 1083 } |
1073 | 1084 |
1074 } | 1085 } |
OLD | NEW |