| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 }; | 91 }; |
| 92 | 92 |
| 93 } // namespace blink | 93 } // namespace blink |
| 94 | 94 |
| 95 WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::AttributeChange); | 95 WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::AttributeChange); |
| 96 | 96 |
| 97 namespace blink { | 97 namespace blink { |
| 98 | 98 |
| 99 class StyledMarkupAccumulator final : public MarkupAccumulator { | 99 class StyledMarkupAccumulator final : public MarkupAccumulator { |
| 100 public: | 100 public: |
| 101 enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode }; | |
| 102 | |
| 103 StyledMarkupAccumulator(Vector<RawPtr<Node> >* nodes, EAbsoluteURLs, EAnnota
teForInterchange, RawPtr<const Range>, Node* highestNodeToBeSerialized = 0); | 101 StyledMarkupAccumulator(Vector<RawPtr<Node> >* nodes, EAbsoluteURLs, EAnnota
teForInterchange, RawPtr<const Range>, Node* highestNodeToBeSerialized = 0); |
| 104 Node* serializeNodes(Node* startNode, Node* pastEnd); | 102 Node* serializeNodes(Node* startNode, Node* pastEnd); |
| 105 void appendString(const String& s) { return MarkupAccumulator::appendString(
s); } | 103 void appendString(const String& s) { return MarkupAccumulator::appendString(
s); } |
| 106 void wrapWithNode(ContainerNode&, bool convertBlocksToInlines = false, Range
FullySelectsNode = DoesFullySelectNode); | 104 void wrapWithNode(ContainerNode&, bool convertBlocksToInlines = false); |
| 107 void wrapWithStyleNode(StylePropertySet*, const Document&, bool isBlock = fa
lse); | 105 void wrapWithStyleNode(StylePropertySet*, const Document&, bool isBlock = fa
lse); |
| 108 String takeResults(); | 106 String takeResults(); |
| 109 | 107 |
| 110 private: | 108 private: |
| 111 void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, const Documen
t&, bool isBlock = false); | 109 void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, const Documen
t&, bool isBlock = false); |
| 112 const String& styleNodeCloseTag(bool isBlock = false); | 110 const String& styleNodeCloseTag(bool isBlock = false); |
| 113 virtual void appendText(StringBuilder& out, Text&) override; | 111 virtual void appendText(StringBuilder& out, Text&) override; |
| 114 String renderedText(Node&, const Range*); | 112 String renderedText(Node&, const Range*); |
| 115 String stringValueForRange(const Node&, const Range*); | 113 String stringValueForRange(const Node&, const Range*); |
| 116 void appendElement(StringBuilder& out, Element&, bool addDisplayInline, Rang
eFullySelectsNode); | 114 void appendElement(StringBuilder& out, Element&, bool addDisplayInline); |
| 117 virtual void appendElement(StringBuilder& out, Element& element, Namespaces*
) override { appendElement(out, element, false, DoesFullySelectNode); } | 115 virtual void appendElement(StringBuilder& out, Element& element, Namespaces*
) override { appendElement(out, element, false); } |
| 118 | 116 |
| 119 enum NodeTraversalMode { EmitString, DoNotEmitString }; | 117 enum NodeTraversalMode { EmitString, DoNotEmitString }; |
| 120 Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTrav
ersalMode); | 118 Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTrav
ersalMode); |
| 121 | 119 |
| 122 bool shouldAnnotate() const { return m_shouldAnnotate == AnnotateForIntercha
nge || m_shouldAnnotate == AnnotateForNavigationTransition; } | 120 bool shouldAnnotate() const { return m_shouldAnnotate == AnnotateForIntercha
nge || m_shouldAnnotate == AnnotateForNavigationTransition; } |
| 123 bool shouldApplyWrappingStyle(const Node& node) const | 121 bool shouldApplyWrappingStyle(const Node& node) const |
| 124 { | 122 { |
| 125 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->paren
tNode() == node.parentNode() | 123 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->paren
tNode() == node.parentNode() |
| 126 && m_wrappingStyle && m_wrappingStyle->style(); | 124 && m_wrappingStyle && m_wrappingStyle->style(); |
| 127 } | 125 } |
| 128 | 126 |
| 129 Vector<String> m_reversedPrecedingMarkup; | 127 Vector<String> m_reversedPrecedingMarkup; |
| 130 const EAnnotateForInterchange m_shouldAnnotate; | 128 const EAnnotateForInterchange m_shouldAnnotate; |
| 131 RawPtr<Node> m_highestNodeToBeSerialized; | 129 RawPtr<Node> m_highestNodeToBeSerialized; |
| 132 RefPtr<EditingStyle> m_wrappingStyle; | 130 RefPtr<EditingStyle> m_wrappingStyle; |
| 133 }; | 131 }; |
| 134 | 132 |
| 135 inline StyledMarkupAccumulator::StyledMarkupAccumulator(Vector<RawPtr<Node> >* n
odes, EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, R
awPtr<const Range> range, Node* highestNodeToBeSerialized) | 133 inline StyledMarkupAccumulator::StyledMarkupAccumulator(Vector<RawPtr<Node> >* n
odes, EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, R
awPtr<const Range> range, Node* highestNodeToBeSerialized) |
| 136 : MarkupAccumulator(nodes, shouldResolveURLs, range) | 134 : MarkupAccumulator(nodes, shouldResolveURLs, range) |
| 137 , m_shouldAnnotate(shouldAnnotate) | 135 , m_shouldAnnotate(shouldAnnotate) |
| 138 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) | 136 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) |
| 139 { | 137 { |
| 140 } | 138 } |
| 141 | 139 |
| 142 void StyledMarkupAccumulator::wrapWithNode(ContainerNode& node, bool convertBloc
ksToInlines, RangeFullySelectsNode rangeFullySelectsNode) | 140 void StyledMarkupAccumulator::wrapWithNode(ContainerNode& node, bool convertBloc
ksToInlines) |
| 143 { | 141 { |
| 144 StringBuilder markup; | 142 StringBuilder markup; |
| 145 if (node.isElementNode()) | 143 if (node.isElementNode()) |
| 146 appendElement(markup, toElement(node), convertBlocksToInlines && isBlock
(&node), rangeFullySelectsNode); | 144 appendElement(markup, toElement(node), convertBlocksToInlines && isBlock
(&node)); |
| 147 else | 145 else |
| 148 appendStartMarkup(markup, node, 0); | 146 appendStartMarkup(markup, node, 0); |
| 149 m_reversedPrecedingMarkup.append(markup.toString()); | 147 m_reversedPrecedingMarkup.append(markup.toString()); |
| 150 if (node.isElementNode()) | 148 if (node.isElementNode()) |
| 151 appendEndTag(toElement(node)); | 149 appendEndTag(toElement(node)); |
| 152 if (m_nodes) | 150 if (m_nodes) |
| 153 m_nodes->append(&node); | 151 m_nodes->append(&node); |
| 154 } | 152 } |
| 155 | 153 |
| 156 void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style, const D
ocument& document, bool isBlock) | 154 void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style, const D
ocument& document, bool isBlock) |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 String text = toText(node).data(); | 222 String text = toText(node).data(); |
| 225 if (!range) | 223 if (!range) |
| 226 return text; | 224 return text; |
| 227 if (node == range->endContainer()) | 225 if (node == range->endContainer()) |
| 228 text.truncate(range->endOffset()); | 226 text.truncate(range->endOffset()); |
| 229 if (node == range->startContainer()) | 227 if (node == range->startContainer()) |
| 230 text.remove(0, range->startOffset()); | 228 text.remove(0, range->startOffset()); |
| 231 return text; | 229 return text; |
| 232 } | 230 } |
| 233 | 231 |
| 234 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element& element
, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode) | 232 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element& element
, bool addDisplayInline) |
| 235 { | 233 { |
| 236 const bool documentIsHTML = element.document().isHTMLDocument(); | 234 const bool documentIsHTML = element.document().isHTMLDocument(); |
| 237 appendOpenTag(out, element, 0); | 235 appendOpenTag(out, element, 0); |
| 238 | 236 |
| 239 const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldA
nnotate() || addDisplayInline); | 237 const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldA
nnotate() || addDisplayInline); |
| 240 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp
plyWrappingStyle(element); | 238 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp
plyWrappingStyle(element); |
| 241 | 239 |
| 242 AttributeCollection attributes = element.attributes(); | 240 AttributeCollection attributes = element.attributes(); |
| 243 AttributeCollection::iterator end = attributes.end(); | 241 AttributeCollection::iterator end = attributes.end(); |
| 244 for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it)
{ | 242 for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it)
{ |
| (...skipping 18 matching lines...) Expand all Loading... |
| 263 | 261 |
| 264 if (shouldAnnotateOrForceInline) { | 262 if (shouldAnnotateOrForceInline) { |
| 265 if (shouldAnnotate()) | 263 if (shouldAnnotate()) |
| 266 newInlineStyle->mergeStyleFromRulesForSerialization(&toHTMLEleme
nt(element)); | 264 newInlineStyle->mergeStyleFromRulesForSerialization(&toHTMLEleme
nt(element)); |
| 267 | 265 |
| 268 if (&element == m_highestNodeToBeSerialized && m_shouldAnnotate == A
nnotateForNavigationTransition) | 266 if (&element == m_highestNodeToBeSerialized && m_shouldAnnotate == A
nnotateForNavigationTransition) |
| 269 newInlineStyle->addAbsolutePositioningFromElement(element); | 267 newInlineStyle->addAbsolutePositioningFromElement(element); |
| 270 | 268 |
| 271 if (addDisplayInline) | 269 if (addDisplayInline) |
| 272 newInlineStyle->forceInline(); | 270 newInlineStyle->forceInline(); |
| 273 | |
| 274 // If the node is not fully selected by the range, then we don't wan
t to keep styles that affect its relationship to the nodes around it | |
| 275 // only the ones that affect it and the nodes within it. | |
| 276 if (rangeFullySelectsNode == DoesNotFullySelectNode && newInlineStyl
e->style()) | |
| 277 newInlineStyle->style()->removeProperty(CSSPropertyFloat); | |
| 278 } | 271 } |
| 279 | 272 |
| 280 if (!newInlineStyle->isEmpty()) { | 273 if (!newInlineStyle->isEmpty()) { |
| 281 out.appendLiteral(" style=\""); | 274 out.appendLiteral(" style=\""); |
| 282 appendAttributeValue(out, newInlineStyle->style()->asText(), documen
tIsHTML); | 275 appendAttributeValue(out, newInlineStyle->style()->asText(), documen
tIsHTML); |
| 283 out.append('\"'); | 276 out.append('\"'); |
| 284 } | 277 } |
| 285 } | 278 } |
| 286 | 279 |
| 287 appendCloseTag(out, element); | 280 appendCloseTag(out, element); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 // Reset the CSS properties to avoid an assertion error in a
ddStyleMarkup(). | 486 // Reset the CSS properties to avoid an assertion error in a
ddStyleMarkup(). |
| 494 // This assertion is caused at least when we select all text
of a <body> element whose | 487 // This assertion is caused at least when we select all text
of a <body> element whose |
| 495 // 'text-decoration' property is "inherit", and copy it. | 488 // 'text-decoration' property is "inherit", and copy it. |
| 496 if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->st
yle(), CSSPropertyTextDecoration)) | 489 if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->st
yle(), CSSPropertyTextDecoration)) |
| 497 fullySelectedRootStyle->style()->setProperty(CSSProperty
TextDecoration, CSSValueNone); | 490 fullySelectedRootStyle->style()->setProperty(CSSProperty
TextDecoration, CSSValueNone); |
| 498 if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->st
yle(), CSSPropertyWebkitTextDecorationsInEffect)) | 491 if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->st
yle(), CSSPropertyWebkitTextDecorationsInEffect)) |
| 499 fullySelectedRootStyle->style()->setProperty(CSSProperty
WebkitTextDecorationsInEffect, CSSValueNone); | 492 fullySelectedRootStyle->style()->setProperty(CSSProperty
WebkitTextDecorationsInEffect, CSSValueNone); |
| 500 accumulator.wrapWithStyleNode(fullySelectedRootStyle->style(
), document, true); | 493 accumulator.wrapWithStyleNode(fullySelectedRootStyle->style(
), document, true); |
| 501 } | 494 } |
| 502 } else { | 495 } else { |
| 503 // Since this node and all the other ancestors are not in the se
lection we want to set RangeFullySelectsNode to DoesNotFullySelectNode | 496 accumulator.wrapWithNode(*ancestor, convertBlocksToInlines); |
| 504 // so that styles that affect the exterior of the node are not i
ncluded. | |
| 505 accumulator.wrapWithNode(*ancestor, convertBlocksToInlines, Styl
edMarkupAccumulator::DoesNotFullySelectNode); | |
| 506 } | 497 } |
| 507 if (nodes) | 498 if (nodes) |
| 508 nodes->append(ancestor); | 499 nodes->append(ancestor); |
| 509 | 500 |
| 510 if (ancestor == specialCommonAncestor) | 501 if (ancestor == specialCommonAncestor) |
| 511 break; | 502 break; |
| 512 } | 503 } |
| 513 } | 504 } |
| 514 | 505 |
| 515 // FIXME: The interchange newline should be placed in the block that it's in
, not after all of the content, unconditionally. | 506 // FIXME: The interchange newline should be placed in the block that it's in
, not after all of the content, unconditionally. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 if (!next || !next->isTextNode()) | 565 if (!next || !next->isTextNode()) |
| 575 return; | 566 return; |
| 576 | 567 |
| 577 RefPtr<Text> textNext = toText(next); | 568 RefPtr<Text> textNext = toText(next); |
| 578 textNode->appendData(textNext->data()); | 569 textNode->appendData(textNext->data()); |
| 579 if (textNext->parentNode()) // Might have been removed by mutation event. | 570 if (textNext->parentNode()) // Might have been removed by mutation event. |
| 580 textNext->remove(exceptionState); | 571 textNext->remove(exceptionState); |
| 581 } | 572 } |
| 582 | 573 |
| 583 } | 574 } |
| OLD | NEW |