| 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 21 matching lines...) Expand all Loading... |
| 32 #include "core/css/StylePropertySet.h" | 32 #include "core/css/StylePropertySet.h" |
| 33 #include "core/dom/Text.h" | 33 #include "core/dom/Text.h" |
| 34 #include "core/editing/htmlediting.h" | 34 #include "core/editing/htmlediting.h" |
| 35 #include "core/editing/iterators/TextIterator.h" | 35 #include "core/editing/iterators/TextIterator.h" |
| 36 #include "wtf/text/StringBuilder.h" | 36 #include "wtf/text/StringBuilder.h" |
| 37 | 37 |
| 38 namespace blink { | 38 namespace blink { |
| 39 | 39 |
| 40 using namespace HTMLNames; | 40 using namespace HTMLNames; |
| 41 | 41 |
| 42 StyledMarkupAccumulator::StyledMarkupAccumulator(EAbsoluteURLs shouldResolveURLs
, const TextOffset& start, const TextOffset& end, const PassRefPtrWillBeRawPtr<D
ocument> document, EAnnotateForInterchange shouldAnnotate, Node* highestNodeToBe
Serialized, ConvertBlocksToInlines convertBlocksToInlines) | 42 StyledMarkupAccumulator::StyledMarkupAccumulator(EAbsoluteURLs shouldResolveURLs
, const TextOffset& start, const TextOffset& end, const PassRefPtrWillBeRawPtr<D
ocument> document, EAnnotateForInterchange shouldAnnotate, Node* highestNodeToBe
Serialized) |
| 43 : m_formatter(shouldResolveURLs) | 43 : m_formatter(shouldResolveURLs) |
| 44 , m_start(start) | 44 , m_start(start) |
| 45 , m_end(end) | 45 , m_end(end) |
| 46 , m_document(document) | 46 , m_document(document) |
| 47 , m_shouldAnnotate(shouldAnnotate) | 47 , m_shouldAnnotate(shouldAnnotate) |
| 48 , m_convertBlocksToInlines(convertBlocksToInlines) | |
| 49 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) | 48 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) |
| 50 { | 49 { |
| 51 } | 50 } |
| 52 | 51 |
| 53 void StyledMarkupAccumulator::appendString(const String& str) | 52 void StyledMarkupAccumulator::appendString(const String& str) |
| 54 { | 53 { |
| 55 m_result.append(str); | 54 m_result.append(str); |
| 56 } | 55 } |
| 57 | 56 |
| 58 void StyledMarkupAccumulator::appendStartTag(Node& node) | 57 void StyledMarkupAccumulator::appendStartTag(Node& node) |
| 59 { | 58 { |
| 60 appendStartMarkup(m_result, node); | 59 appendStartMarkup(m_result, node); |
| 61 } | 60 } |
| 62 | 61 |
| 63 void StyledMarkupAccumulator::appendEndTag(const Element& element) | 62 void StyledMarkupAccumulator::appendEndTag(const Element& element) |
| 64 { | 63 { |
| 65 appendEndMarkup(m_result, element); | 64 appendEndMarkup(m_result, element); |
| 66 } | 65 } |
| 67 | 66 |
| 68 void StyledMarkupAccumulator::appendStartMarkup(StringBuilder& result, Node& nod
e) | 67 void StyledMarkupAccumulator::appendStartMarkup(StringBuilder& result, Node& nod
e) |
| 69 { | 68 { |
| 70 switch (node.nodeType()) { | 69 m_formatter.appendStartMarkup(result, node, nullptr); |
| 71 case Node::TEXT_NODE: | |
| 72 appendText(result, toText(node)); | |
| 73 break; | |
| 74 case Node::ELEMENT_NODE: | |
| 75 appendElement(result, toElement(node)); | |
| 76 break; | |
| 77 default: | |
| 78 m_formatter.appendStartMarkup(result, node, nullptr); | |
| 79 break; | |
| 80 } | |
| 81 } | 70 } |
| 82 | 71 |
| 83 void StyledMarkupAccumulator::appendEndMarkup(StringBuilder& result, const Eleme
nt& element) | 72 void StyledMarkupAccumulator::appendEndMarkup(StringBuilder& result, const Eleme
nt& element) |
| 84 { | 73 { |
| 85 m_formatter.appendEndMarkup(result, element); | 74 m_formatter.appendEndMarkup(result, element); |
| 86 } | 75 } |
| 87 | 76 |
| 77 void StyledMarkupAccumulator::appendText(Text& text) |
| 78 { |
| 79 appendText(m_result, text); |
| 80 } |
| 81 |
| 88 void StyledMarkupAccumulator::appendText(StringBuilder& out, Text& text) | 82 void StyledMarkupAccumulator::appendText(StringBuilder& out, Text& text) |
| 89 { | 83 { |
| 90 const bool parentIsTextarea = text.parentElement() && text.parentElement()->
tagQName() == textareaTag; | 84 const bool parentIsTextarea = text.parentElement() && text.parentElement()->
tagQName() == textareaTag; |
| 91 const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextare
a; | 85 const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextare
a; |
| 92 if (wrappingSpan) { | 86 if (wrappingSpan) { |
| 93 RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy()
; | 87 RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy()
; |
| 94 // FIXME: <rdar://problem/5371536> Style rules that match pasted content
can change it's appearance | 88 // FIXME: <rdar://problem/5371536> Style rules that match pasted content
can change it's appearance |
| 95 // Make sure spans are inline style in paste side e.g. span { display: b
lock }. | 89 // Make sure spans are inline style in paste side e.g. span { display: b
lock }. |
| 96 wrappingStyle->forceInline(); | 90 wrappingStyle->forceInline(); |
| 97 // FIXME: Should this be included in forceInline? | 91 // FIXME: Should this be included in forceInline? |
| (...skipping 28 matching lines...) Expand all Loading... |
| 126 String content = useRenderedText ? renderedText(text) : stringValueForRa
nge(text); | 120 String content = useRenderedText ? renderedText(text) : stringValueForRa
nge(text); |
| 127 StringBuilder buffer; | 121 StringBuilder buffer; |
| 128 MarkupFormatter::appendCharactersReplacingEntities(buffer, content, 0, c
ontent.length(), EntityMaskInPCDATA); | 122 MarkupFormatter::appendCharactersReplacingEntities(buffer, content, 0, c
ontent.length(), EntityMaskInPCDATA); |
| 129 out.append(convertHTMLTextToInterchangeFormat(buffer.toString(), text)); | 123 out.append(convertHTMLTextToInterchangeFormat(buffer.toString(), text)); |
| 130 } | 124 } |
| 131 | 125 |
| 132 if (wrappingSpan) | 126 if (wrappingSpan) |
| 133 out.append("</span>"); | 127 out.append("</span>"); |
| 134 } | 128 } |
| 135 | 129 |
| 136 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element& element
) | 130 RefPtrWillBeMember<EditingStyle> StyledMarkupAccumulator::createInlineStyle(Elem
ent& element, bool addDisplayInline) |
| 137 { | 131 { |
| 138 appendElement(out, element, false, DoesFullySelectNode); | 132 const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldA
nnotate() || addDisplayInline); |
| 133 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp
plyWrappingStyle(element); |
| 134 |
| 135 if (!shouldOverrideStyleAttr) |
| 136 return nullptr; |
| 137 |
| 138 RefPtrWillBeRawPtr<EditingStyle> inlineStyle = nullptr; |
| 139 |
| 140 if (shouldApplyWrappingStyle(element)) { |
| 141 inlineStyle = m_wrappingStyle->copy(); |
| 142 inlineStyle->removePropertiesInElementDefaultStyle(&element); |
| 143 inlineStyle->removeStyleConflictingWithStyleOfElement(&element); |
| 144 } else { |
| 145 inlineStyle = EditingStyle::create(); |
| 146 } |
| 147 |
| 148 if (element.isStyledElement() && element.inlineStyle()) |
| 149 inlineStyle->overrideWithStyle(element.inlineStyle()); |
| 150 |
| 151 if (shouldAnnotateOrForceInline) { |
| 152 if (shouldAnnotate()) |
| 153 inlineStyle->mergeStyleFromRulesForSerialization(&toHTMLElement(elem
ent)); |
| 154 |
| 155 if (addDisplayInline) |
| 156 inlineStyle->forceInline(); |
| 157 } |
| 158 |
| 159 return inlineStyle; |
| 139 } | 160 } |
| 140 | 161 |
| 141 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element& element
, bool addDisplayInline, StyledMarkupAccumulator::RangeFullySelectsNode rangeFul
lySelectsNode) | 162 void StyledMarkupAccumulator::appendElement(Element& element, bool addDisplayInl
ine, PassRefPtrWillBeRawPtr<EditingStyle> style) |
| 163 { |
| 164 appendElement(m_result, element, addDisplayInline, style); |
| 165 } |
| 166 |
| 167 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element& element
, bool addDisplayInline, PassRefPtrWillBeRawPtr<EditingStyle> style) |
| 142 { | 168 { |
| 143 const bool documentIsHTML = element.document().isHTMLDocument(); | 169 const bool documentIsHTML = element.document().isHTMLDocument(); |
| 144 m_formatter.appendOpenTag(out, element, 0); | 170 m_formatter.appendOpenTag(out, element, nullptr); |
| 145 | 171 |
| 146 const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldA
nnotate() || addDisplayInline); | 172 const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldA
nnotate() || addDisplayInline); |
| 147 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp
plyWrappingStyle(element); | 173 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldAp
plyWrappingStyle(element); |
| 148 | 174 |
| 149 AttributeCollection attributes = element.attributes(); | 175 AttributeCollection attributes = element.attributes(); |
| 150 for (const auto& attribute : attributes) { | 176 for (const auto& attribute : attributes) { |
| 151 // We'll handle the style attribute separately, below. | 177 // We'll handle the style attribute separately, below. |
| 152 if (attribute.name() == styleAttr && shouldOverrideStyleAttr) | 178 if (attribute.name() == styleAttr && shouldOverrideStyleAttr) |
| 153 continue; | 179 continue; |
| 154 m_formatter.appendAttribute(out, element, attribute, nullptr); | 180 m_formatter.appendAttribute(out, element, attribute, nullptr); |
| 155 } | 181 } |
| 156 | 182 |
| 157 if (shouldOverrideStyleAttr) { | 183 if (shouldOverrideStyleAttr) { |
| 158 RefPtrWillBeRawPtr<EditingStyle> newInlineStyle = nullptr; | 184 if (style && !style->isEmpty()) { |
| 159 | |
| 160 if (shouldApplyWrappingStyle(element)) { | |
| 161 newInlineStyle = m_wrappingStyle->copy(); | |
| 162 newInlineStyle->removePropertiesInElementDefaultStyle(&element); | |
| 163 newInlineStyle->removeStyleConflictingWithStyleOfElement(&element); | |
| 164 } else { | |
| 165 newInlineStyle = EditingStyle::create(); | |
| 166 } | |
| 167 | |
| 168 if (element.isStyledElement() && element.inlineStyle()) | |
| 169 newInlineStyle->overrideWithStyle(element.inlineStyle()); | |
| 170 | |
| 171 if (shouldAnnotateOrForceInline) { | |
| 172 if (shouldAnnotate()) | |
| 173 newInlineStyle->mergeStyleFromRulesForSerialization(&toHTMLEleme
nt(element)); | |
| 174 | |
| 175 if (addDisplayInline) | |
| 176 newInlineStyle->forceInline(); | |
| 177 | |
| 178 // 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 | |
| 179 // only the ones that affect it and the nodes within it. | |
| 180 if (rangeFullySelectsNode == DoesNotFullySelectNode && newInlineStyl
e->style()) | |
| 181 newInlineStyle->style()->removeProperty(CSSPropertyFloat); | |
| 182 } | |
| 183 | |
| 184 if (!newInlineStyle->isEmpty()) { | |
| 185 out.appendLiteral(" style=\""); | 185 out.appendLiteral(" style=\""); |
| 186 MarkupFormatter::appendAttributeValue(out, newInlineStyle->style()->
asText(), documentIsHTML); | 186 MarkupFormatter::appendAttributeValue(out, style->style()->asText(),
documentIsHTML); |
| 187 out.append('\"'); | 187 out.append('\"'); |
| 188 } | 188 } |
| 189 } | 189 } |
| 190 | 190 |
| 191 m_formatter.appendCloseTag(out, element); | 191 m_formatter.appendCloseTag(out, element); |
| 192 } | 192 } |
| 193 | 193 |
| 194 void StyledMarkupAccumulator::wrapWithNode(ContainerNode& node, RangeFullySelect
sNode rangeFullySelectsNode) | 194 void StyledMarkupAccumulator::pushMarkup(const String& str) |
| 195 { | 195 { |
| 196 StringBuilder markup; | 196 m_reversedPrecedingMarkup.append(str); |
| 197 if (node.isElementNode()) | |
| 198 appendElement(markup, toElement(node), convertBlocksToInlines() && isBlo
ck(&node), rangeFullySelectsNode); | |
| 199 else | |
| 200 appendStartMarkup(markup, node); | |
| 201 m_reversedPrecedingMarkup.append(markup.toString()); | |
| 202 if (node.isElementNode()) | |
| 203 appendEndTag(toElement(node)); | |
| 204 } | 197 } |
| 205 | 198 |
| 206 void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style) | 199 void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style) |
| 207 { | 200 { |
| 208 // wrappingStyleForSerialization should have removed -webkit-text-decoration
s-in-effect | 201 // wrappingStyleForSerialization should have removed -webkit-text-decoration
s-in-effect |
| 209 ASSERT(propertyMissingOrEqualToNone(style, CSSPropertyWebkitTextDecorationsI
nEffect)); | 202 ASSERT(propertyMissingOrEqualToNone(style, CSSPropertyWebkitTextDecorationsI
nEffect)); |
| 210 ASSERT(m_document); | 203 ASSERT(m_document); |
| 211 | 204 |
| 212 StringBuilder openTag; | 205 StringBuilder openTag; |
| 213 openTag.appendLiteral("<div style=\""); | 206 openTag.appendLiteral("<div style=\""); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNod
e() == node.parentNode() | 255 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNod
e() == node.parentNode() |
| 263 && m_wrappingStyle && m_wrappingStyle->style(); | 256 && m_wrappingStyle && m_wrappingStyle->style(); |
| 264 } | 257 } |
| 265 | 258 |
| 266 bool StyledMarkupAccumulator::shouldAnnotate() const | 259 bool StyledMarkupAccumulator::shouldAnnotate() const |
| 267 { | 260 { |
| 268 return m_shouldAnnotate == AnnotateForInterchange; | 261 return m_shouldAnnotate == AnnotateForInterchange; |
| 269 } | 262 } |
| 270 | 263 |
| 271 } // namespace blink | 264 } // namespace blink |
| OLD | NEW |