| 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 19 matching lines...) Expand all Loading... |
| 30 #include "core/editing/StyledMarkupAccumulator.h" | 30 #include "core/editing/StyledMarkupAccumulator.h" |
| 31 | 31 |
| 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 namespace { | |
| 41 | |
| 42 const String& styleNodeCloseTag(bool isBlock) | |
| 43 { | |
| 44 DEFINE_STATIC_LOCAL(const String, divClose, ("</div>")); | |
| 45 DEFINE_STATIC_LOCAL(const String, styleSpanClose, ("</span>")); | |
| 46 return isBlock ? divClose : styleSpanClose; | |
| 47 } | |
| 48 | |
| 49 } // namespace | |
| 50 | |
| 51 using namespace HTMLNames; | 40 using namespace HTMLNames; |
| 52 | 41 |
| 53 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, ConvertBlocksToInlines convertBlocksToInlines) |
| 54 : m_formatter(shouldResolveURLs) | 43 : m_formatter(shouldResolveURLs) |
| 55 , m_start(start) | 44 , m_start(start) |
| 56 , m_end(end) | 45 , m_end(end) |
| 57 , m_document(document) | 46 , m_document(document) |
| 58 , m_shouldAnnotate(shouldAnnotate) | 47 , m_shouldAnnotate(shouldAnnotate) |
| 59 , m_convertBlocksToInlines(convertBlocksToInlines) | 48 , m_convertBlocksToInlines(convertBlocksToInlines) |
| 60 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) | 49 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 const bool parentIsTextarea = text.parentElement() && text.parentElement()->
tagQName() == textareaTag; | 90 const bool parentIsTextarea = text.parentElement() && text.parentElement()->
tagQName() == textareaTag; |
| 102 const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextare
a; | 91 const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextare
a; |
| 103 if (wrappingSpan) { | 92 if (wrappingSpan) { |
| 104 RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy()
; | 93 RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy()
; |
| 105 // FIXME: <rdar://problem/5371536> Style rules that match pasted content
can change it's appearance | 94 // FIXME: <rdar://problem/5371536> Style rules that match pasted content
can change it's appearance |
| 106 // Make sure spans are inline style in paste side e.g. span { display: b
lock }. | 95 // Make sure spans are inline style in paste side e.g. span { display: b
lock }. |
| 107 wrappingStyle->forceInline(); | 96 wrappingStyle->forceInline(); |
| 108 // FIXME: Should this be included in forceInline? | 97 // FIXME: Should this be included in forceInline? |
| 109 wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone); | 98 wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone); |
| 110 | 99 |
| 111 appendStyleNodeOpenTag(out, wrappingStyle->style()); | 100 // wrappingStyleForSerialization should have removed -webkit-text-decora
tions-in-effect |
| 101 ASSERT(propertyMissingOrEqualToNone(wrappingStyle->style(), CSSPropertyW
ebkitTextDecorationsInEffect)); |
| 102 ASSERT(m_document); |
| 103 |
| 104 out.appendLiteral("<span style=\""); |
| 105 MarkupFormatter::appendAttributeValue(out, wrappingStyle->style()->asTex
t(), m_document->isHTMLDocument()); |
| 106 out.appendLiteral("\">"); |
| 112 } | 107 } |
| 113 | 108 |
| 114 if (!shouldAnnotate() || parentIsTextarea) { | 109 if (!shouldAnnotate() || parentIsTextarea) { |
| 115 const String& str = text.data(); | 110 const String& str = text.data(); |
| 116 unsigned length = str.length(); | 111 unsigned length = str.length(); |
| 117 unsigned start = 0; | 112 unsigned start = 0; |
| 118 if (m_end.isNotNull()) { | 113 if (m_end.isNotNull()) { |
| 119 if (text == m_end.text()) | 114 if (text == m_end.text()) |
| 120 length = m_end.offset(); | 115 length = m_end.offset(); |
| 121 } | 116 } |
| 122 if (m_start.isNotNull()) { | 117 if (m_start.isNotNull()) { |
| 123 if (text == m_start.text()) { | 118 if (text == m_start.text()) { |
| 124 start = m_start.offset(); | 119 start = m_start.offset(); |
| 125 length -= start; | 120 length -= start; |
| 126 } | 121 } |
| 127 } | 122 } |
| 128 MarkupFormatter::appendCharactersReplacingEntities(out, str, start, leng
th, m_formatter.entityMaskForText(text)); | 123 MarkupFormatter::appendCharactersReplacingEntities(out, str, start, leng
th, m_formatter.entityMaskForText(text)); |
| 129 } else { | 124 } else { |
| 130 const bool useRenderedText = !enclosingElementWithTag(firstPositionInNod
e(&text), selectTag); | 125 const bool useRenderedText = !enclosingElementWithTag(firstPositionInNod
e(&text), selectTag); |
| 131 String content = useRenderedText ? renderedText(text) : stringValueForRa
nge(text); | 126 String content = useRenderedText ? renderedText(text) : stringValueForRa
nge(text); |
| 132 StringBuilder buffer; | 127 StringBuilder buffer; |
| 133 MarkupFormatter::appendCharactersReplacingEntities(buffer, content, 0, c
ontent.length(), EntityMaskInPCDATA); | 128 MarkupFormatter::appendCharactersReplacingEntities(buffer, content, 0, c
ontent.length(), EntityMaskInPCDATA); |
| 134 out.append(convertHTMLTextToInterchangeFormat(buffer.toString(), text)); | 129 out.append(convertHTMLTextToInterchangeFormat(buffer.toString(), text)); |
| 135 } | 130 } |
| 136 | 131 |
| 137 if (wrappingSpan) | 132 if (wrappingSpan) |
| 138 out.append(styleNodeCloseTag(false)); | 133 out.append("</span>"); |
| 139 } | 134 } |
| 140 | 135 |
| 141 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element& element
) | 136 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element& element
) |
| 142 { | 137 { |
| 143 appendElement(out, element, false, DoesFullySelectNode); | 138 appendElement(out, element, false, DoesFullySelectNode); |
| 144 } | 139 } |
| 145 | 140 |
| 146 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element& element
, bool addDisplayInline, StyledMarkupAccumulator::RangeFullySelectsNode rangeFul
lySelectsNode) | 141 void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element& element
, bool addDisplayInline, StyledMarkupAccumulator::RangeFullySelectsNode rangeFul
lySelectsNode) |
| 147 { | 142 { |
| 148 const bool documentIsHTML = element.document().isHTMLDocument(); | 143 const bool documentIsHTML = element.document().isHTMLDocument(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 if (!newInlineStyle->isEmpty()) { | 184 if (!newInlineStyle->isEmpty()) { |
| 190 out.appendLiteral(" style=\""); | 185 out.appendLiteral(" style=\""); |
| 191 MarkupFormatter::appendAttributeValue(out, newInlineStyle->style()->
asText(), documentIsHTML); | 186 MarkupFormatter::appendAttributeValue(out, newInlineStyle->style()->
asText(), documentIsHTML); |
| 192 out.append('\"'); | 187 out.append('\"'); |
| 193 } | 188 } |
| 194 } | 189 } |
| 195 | 190 |
| 196 m_formatter.appendCloseTag(out, element); | 191 m_formatter.appendCloseTag(out, element); |
| 197 } | 192 } |
| 198 | 193 |
| 199 void StyledMarkupAccumulator::appendStyleNodeOpenTag(StringBuilder& out, StylePr
opertySet* style, bool isBlock) | |
| 200 { | |
| 201 // wrappingStyleForSerialization should have removed -webkit-text-decoration
s-in-effect | |
| 202 ASSERT(propertyMissingOrEqualToNone(style, CSSPropertyWebkitTextDecorationsI
nEffect)); | |
| 203 if (isBlock) | |
| 204 out.appendLiteral("<div style=\""); | |
| 205 else | |
| 206 out.appendLiteral("<span style=\""); | |
| 207 ASSERT(m_document); | |
| 208 MarkupFormatter::appendAttributeValue(out, style->asText(), m_document->isHT
MLDocument()); | |
| 209 out.appendLiteral("\">"); | |
| 210 } | |
| 211 | |
| 212 void StyledMarkupAccumulator::wrapWithNode(ContainerNode& node, RangeFullySelect
sNode rangeFullySelectsNode) | 194 void StyledMarkupAccumulator::wrapWithNode(ContainerNode& node, RangeFullySelect
sNode rangeFullySelectsNode) |
| 213 { | 195 { |
| 214 StringBuilder markup; | 196 StringBuilder markup; |
| 215 if (node.isElementNode()) | 197 if (node.isElementNode()) |
| 216 appendElement(markup, toElement(node), convertBlocksToInlines() && isBlo
ck(&node), rangeFullySelectsNode); | 198 appendElement(markup, toElement(node), convertBlocksToInlines() && isBlo
ck(&node), rangeFullySelectsNode); |
| 217 else | 199 else |
| 218 appendStartMarkup(markup, node); | 200 appendStartMarkup(markup, node); |
| 219 m_reversedPrecedingMarkup.append(markup.toString()); | 201 m_reversedPrecedingMarkup.append(markup.toString()); |
| 220 if (node.isElementNode()) | 202 if (node.isElementNode()) |
| 221 appendEndTag(toElement(node)); | 203 appendEndTag(toElement(node)); |
| 222 } | 204 } |
| 223 | 205 |
| 224 void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style, bool is
Block) | 206 void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style) |
| 225 { | 207 { |
| 208 // wrappingStyleForSerialization should have removed -webkit-text-decoration
s-in-effect |
| 209 ASSERT(propertyMissingOrEqualToNone(style, CSSPropertyWebkitTextDecorationsI
nEffect)); |
| 210 ASSERT(m_document); |
| 211 |
| 226 StringBuilder openTag; | 212 StringBuilder openTag; |
| 227 appendStyleNodeOpenTag(openTag, style, isBlock); | 213 openTag.appendLiteral("<div style=\""); |
| 214 MarkupFormatter::appendAttributeValue(openTag, style->asText(), m_document->
isHTMLDocument()); |
| 215 openTag.appendLiteral("\">"); |
| 228 m_reversedPrecedingMarkup.append(openTag.toString()); | 216 m_reversedPrecedingMarkup.append(openTag.toString()); |
| 229 appendString(styleNodeCloseTag(isBlock)); | 217 |
| 218 appendString("</div>"); |
| 230 } | 219 } |
| 231 | 220 |
| 232 String StyledMarkupAccumulator::takeResults() | 221 String StyledMarkupAccumulator::takeResults() |
| 233 { | 222 { |
| 234 StringBuilder result; | 223 StringBuilder result; |
| 235 result.reserveCapacity(MarkupFormatter::totalLength(m_reversedPrecedingMarku
p) + m_result.length()); | 224 result.reserveCapacity(MarkupFormatter::totalLength(m_reversedPrecedingMarku
p) + m_result.length()); |
| 236 | 225 |
| 237 for (size_t i = m_reversedPrecedingMarkup.size(); i > 0; --i) | 226 for (size_t i = m_reversedPrecedingMarkup.size(); i > 0; --i) |
| 238 result.append(m_reversedPrecedingMarkup[i - 1]); | 227 result.append(m_reversedPrecedingMarkup[i - 1]); |
| 239 | 228 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNod
e() == node.parentNode() | 262 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNod
e() == node.parentNode() |
| 274 && m_wrappingStyle && m_wrappingStyle->style(); | 263 && m_wrappingStyle && m_wrappingStyle->style(); |
| 275 } | 264 } |
| 276 | 265 |
| 277 bool StyledMarkupAccumulator::shouldAnnotate() const | 266 bool StyledMarkupAccumulator::shouldAnnotate() const |
| 278 { | 267 { |
| 279 return m_shouldAnnotate == AnnotateForInterchange; | 268 return m_shouldAnnotate == AnnotateForInterchange; |
| 280 } | 269 } |
| 281 | 270 |
| 282 } // namespace blink | 271 } // namespace blink |
| OLD | NEW |