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

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

Issue 1148633010: Refactoring: Separate MarkupAccumulator into MarkupFormatter and MarkupAccumulator (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebase Created 5 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/editing/MarkupAccumulator.h ('k') | Source/core/editing/MarkupFormatter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2009, 2010 Google Inc. All rights reserved. 3 * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 29 matching lines...) Expand all
40 #include "core/editing/Editor.h" 40 #include "core/editing/Editor.h"
41 #include "core/html/HTMLElement.h" 41 #include "core/html/HTMLElement.h"
42 #include "core/html/HTMLTemplateElement.h" 42 #include "core/html/HTMLTemplateElement.h"
43 #include "platform/weborigin/KURL.h" 43 #include "platform/weborigin/KURL.h"
44 #include "wtf/unicode/CharacterNames.h" 44 #include "wtf/unicode/CharacterNames.h"
45 45
46 namespace blink { 46 namespace blink {
47 47
48 using namespace HTMLNames; 48 using namespace HTMLNames;
49 49
50 struct EntityDescription {
51 UChar entity;
52 const CString& reference;
53 EntityMask mask;
54 };
55
56 template <typename CharType>
57 static inline void appendCharactersReplacingEntitiesInternal(StringBuilder& resu lt, CharType* text, unsigned length, const EntityDescription entityMaps[], unsig ned entityMapsCount, EntityMask entityMask)
58 {
59 unsigned positionAfterLastEntity = 0;
60 for (unsigned i = 0; i < length; ++i) {
61 for (unsigned entityIndex = 0; entityIndex < entityMapsCount; ++entityIn dex) {
62 if (text[i] == entityMaps[entityIndex].entity && entityMaps[entityIn dex].mask & entityMask) {
63 result.append(text + positionAfterLastEntity, i - positionAfterL astEntity);
64 const CString& replacement = entityMaps[entityIndex].reference;
65 result.append(replacement.data(), replacement.length());
66 positionAfterLastEntity = i + 1;
67 break;
68 }
69 }
70 }
71 result.append(text + positionAfterLastEntity, length - positionAfterLastEnti ty);
72 }
73
74 void MarkupAccumulator::appendCharactersReplacingEntities(StringBuilder& result, const String& source, unsigned offset, unsigned length, EntityMask entityMask)
75 {
76 DEFINE_STATIC_LOCAL(const CString, ampReference, ("&amp;"));
77 DEFINE_STATIC_LOCAL(const CString, ltReference, ("&lt;"));
78 DEFINE_STATIC_LOCAL(const CString, gtReference, ("&gt;"));
79 DEFINE_STATIC_LOCAL(const CString, quotReference, ("&quot;"));
80 DEFINE_STATIC_LOCAL(const CString, nbspReference, ("&nbsp;"));
81
82 static const EntityDescription entityMaps[] = {
83 { '&', ampReference, EntityAmp },
84 { '<', ltReference, EntityLt },
85 { '>', gtReference, EntityGt },
86 { '"', quotReference, EntityQuot },
87 { noBreakSpaceCharacter, nbspReference, EntityNbsp },
88 };
89
90 if (!(offset + length))
91 return;
92
93 ASSERT(offset + length <= source.length());
94 if (source.is8Bit())
95 appendCharactersReplacingEntitiesInternal(result, source.characters8() + offset, length, entityMaps, WTF_ARRAY_LENGTH(entityMaps), entityMask);
96 else
97 appendCharactersReplacingEntitiesInternal(result, source.characters16() + offset, length, entityMaps, WTF_ARRAY_LENGTH(entityMaps), entityMask);
98 }
99
100 size_t MarkupAccumulator::totalLength(const Vector<String>& strings)
101 {
102 size_t length = 0;
103 for (const auto& string : strings)
104 length += string.length();
105 return length;
106 }
107
108 MarkupAccumulator::MarkupAccumulator(EAbsoluteURLs resolveUrlsMethod, Serializat ionType serializationType) 50 MarkupAccumulator::MarkupAccumulator(EAbsoluteURLs resolveUrlsMethod, Serializat ionType serializationType)
109 : m_resolveURLsMethod(resolveUrlsMethod) 51 : m_formatter(resolveUrlsMethod, serializationType)
110 , m_serializationType(serializationType)
111 { 52 {
112 } 53 }
113 54
114 MarkupAccumulator::~MarkupAccumulator() 55 MarkupAccumulator::~MarkupAccumulator()
115 { 56 {
116 } 57 }
117 58
118 String MarkupAccumulator::resolveURLIfNeeded(const Element& element, const Strin g& urlString) const
119 {
120 switch (m_resolveURLsMethod) {
121 case ResolveAllURLs:
122 return element.document().completeURL(urlString).string();
123
124 case ResolveNonLocalURLs:
125 if (!element.document().url().isLocalFile())
126 return element.document().completeURL(urlString).string();
127 break;
128
129 case DoNotResolveURLs:
130 break;
131 }
132 return urlString;
133 }
134
135 void MarkupAccumulator::appendString(const String& string) 59 void MarkupAccumulator::appendString(const String& string)
136 { 60 {
137 m_markup.append(string); 61 m_markup.append(string);
138 } 62 }
139 63
140 void MarkupAccumulator::appendStartTag(Node& node, Namespaces* namespaces) 64 void MarkupAccumulator::appendStartTag(Node& node, Namespaces* namespaces)
141 { 65 {
142 appendStartMarkup(m_markup, node, namespaces); 66 appendStartMarkup(m_markup, node, namespaces);
143 } 67 }
144 68
145 void MarkupAccumulator::appendEndTag(const Element& element) 69 void MarkupAccumulator::appendEndTag(const Element& element)
146 { 70 {
147 appendEndMarkup(m_markup, element); 71 appendEndMarkup(m_markup, element);
148 } 72 }
149 73
150 void MarkupAccumulator::appendStartMarkup(StringBuilder& result, Node& node, Nam espaces* namespaces) 74 void MarkupAccumulator::appendStartMarkup(StringBuilder& result, Node& node, Nam espaces* namespaces)
151 { 75 {
152 switch (node.nodeType()) { 76 switch (node.nodeType()) {
153 case Node::TEXT_NODE: 77 case Node::TEXT_NODE:
154 appendText(result, toText(node)); 78 appendText(result, toText(node));
155 break; 79 break;
156 case Node::COMMENT_NODE: 80 case Node::COMMENT_NODE:
157 appendComment(result, toComment(node).data()); 81 MarkupFormatter::appendComment(result, toComment(node).data());
158 break; 82 break;
159 case Node::DOCUMENT_NODE: 83 case Node::DOCUMENT_NODE:
160 appendXMLDeclaration(result, toDocument(node)); 84 appendXMLDeclaration(result, toDocument(node));
161 break; 85 break;
162 case Node::DOCUMENT_FRAGMENT_NODE: 86 case Node::DOCUMENT_FRAGMENT_NODE:
163 break; 87 break;
164 case Node::DOCUMENT_TYPE_NODE: 88 case Node::DOCUMENT_TYPE_NODE:
165 appendDocumentType(result, toDocumentType(node)); 89 appendDocumentType(result, toDocumentType(node));
166 break; 90 break;
167 case Node::PROCESSING_INSTRUCTION_NODE: 91 case Node::PROCESSING_INSTRUCTION_NODE:
(...skipping 18 matching lines...) Expand all
186 110
187 // FIXME: ieForbidsInsertHTML may not be the right function to call here 111 // FIXME: ieForbidsInsertHTML may not be the right function to call here
188 // ieForbidsInsertHTML is used to disallow setting innerHTML/outerHTML 112 // ieForbidsInsertHTML is used to disallow setting innerHTML/outerHTML
189 // or createContextualFragment. It does not necessarily align with 113 // or createContextualFragment. It does not necessarily align with
190 // which elements should be serialized w/o end tags. 114 // which elements should be serialized w/o end tags.
191 return toHTMLElement(node).ieForbidsInsertHTML(); 115 return toHTMLElement(node).ieForbidsInsertHTML();
192 } 116 }
193 117
194 void MarkupAccumulator::appendEndMarkup(StringBuilder& result, const Element& el ement) 118 void MarkupAccumulator::appendEndMarkup(StringBuilder& result, const Element& el ement)
195 { 119 {
196 if (shouldSelfClose(element) || (!element.hasChildren() && elementCannotHave EndTag(element))) 120 m_formatter.appendEndMarkup(result, element);
197 return;
198
199 result.appendLiteral("</");
200 result.append(element.tagQName().toString());
201 result.append('>');
202 } 121 }
203 122
204 void MarkupAccumulator::concatenateMarkup(StringBuilder& result) const 123 void MarkupAccumulator::concatenateMarkup(StringBuilder& result) const
205 { 124 {
206 result.append(m_markup); 125 result.append(m_markup);
207 } 126 }
208 127
209 void MarkupAccumulator::appendAttributeValue(StringBuilder& result, const String & attribute, bool documentIsHTML) 128 void MarkupAccumulator::appendAttributeValue(StringBuilder& result, const String & attribute, bool documentIsHTML)
210 { 129 {
211 appendCharactersReplacingEntities(result, attribute, 0, attribute.length(), 130 m_formatter.appendAttributeValue(result, attribute, documentIsHTML);
212 documentIsHTML ? EntityMaskInHTMLAttributeValue : EntityMaskInAttributeV alue);
213 } 131 }
214 132
215 void MarkupAccumulator::appendCustomAttributes(StringBuilder&, const Element&, N amespaces*) 133 void MarkupAccumulator::appendCustomAttributes(StringBuilder&, const Element&, N amespaces*)
216 { 134 {
217 } 135 }
218 136
219 void MarkupAccumulator::appendQuotedURLAttributeValue(StringBuilder& result, con st Element& element, const Attribute& attribute)
220 {
221 ASSERT(element.isURLAttribute(attribute));
222 const String resolvedURLString = resolveURLIfNeeded(element, attribute.value ());
223 UChar quoteChar = '"';
224 String strippedURLString = resolvedURLString.stripWhiteSpace();
225 if (protocolIsJavaScript(strippedURLString)) {
226 // minimal escaping for javascript urls
227 if (strippedURLString.contains('&'))
228 strippedURLString.replaceWithLiteral('&', "&amp;");
229
230 if (strippedURLString.contains('"')) {
231 if (strippedURLString.contains('\''))
232 strippedURLString.replaceWithLiteral('"', "&quot;");
233 else
234 quoteChar = '\'';
235 }
236 result.append(quoteChar);
237 result.append(strippedURLString);
238 result.append(quoteChar);
239 return;
240 }
241
242 // FIXME: This does not fully match other browsers. Firefox percent-escapes non-ASCII characters for innerHTML.
243 result.append(quoteChar);
244 appendAttributeValue(result, resolvedURLString, false);
245 result.append(quoteChar);
246 }
247
248 void MarkupAccumulator::appendNamespace(StringBuilder& result, const AtomicStrin g& prefix, const AtomicString& namespaceURI, Namespaces& namespaces) 137 void MarkupAccumulator::appendNamespace(StringBuilder& result, const AtomicStrin g& prefix, const AtomicString& namespaceURI, Namespaces& namespaces)
249 { 138 {
250 if (namespaceURI.isEmpty()) 139 m_formatter.appendNamespace(result, prefix, namespaceURI, namespaces);
251 return;
252
253 const AtomicString& lookupKey = (!prefix) ? emptyAtom : prefix;
254 AtomicString foundURI = namespaces.get(lookupKey);
255 if (foundURI != namespaceURI) {
256 namespaces.set(lookupKey, namespaceURI);
257 result.append(' ');
258 result.append(xmlnsAtom.string());
259 if (!prefix.isEmpty()) {
260 result.append(':');
261 result.append(prefix);
262 }
263
264 result.appendLiteral("=\"");
265 appendAttributeValue(result, namespaceURI, false);
266 result.append('"');
267 }
268 } 140 }
269 141
270 void MarkupAccumulator::appendText(StringBuilder& result, Text& text) 142 void MarkupAccumulator::appendText(StringBuilder& result, Text& text)
271 { 143 {
272 const String& str = text.data(); 144 m_formatter.appendText(result, text);
273 appendCharactersReplacingEntities(result, str, 0, str.length(), entityMaskFo rText(text));
274 }
275
276 void MarkupAccumulator::appendComment(StringBuilder& result, const String& comme nt)
277 {
278 // FIXME: Comment content is not escaped, but XMLSerializer (and possibly ot her callers) should raise an exception if it includes "-->".
279 result.appendLiteral("<!--");
280 result.append(comment);
281 result.appendLiteral("-->");
282 } 145 }
283 146
284 void MarkupAccumulator::appendXMLDeclaration(StringBuilder& result, const Docume nt& document) 147 void MarkupAccumulator::appendXMLDeclaration(StringBuilder& result, const Docume nt& document)
285 { 148 {
286 if (!document.hasXMLDeclaration()) 149 m_formatter.appendXMLDeclaration(result, document);
287 return;
288
289 result.appendLiteral("<?xml version=\"");
290 result.append(document.xmlVersion());
291 const String& encoding = document.xmlEncoding();
292 if (!encoding.isEmpty()) {
293 result.appendLiteral("\" encoding=\"");
294 result.append(encoding);
295 }
296 if (document.xmlStandaloneStatus() != Document::StandaloneUnspecified) {
297 result.appendLiteral("\" standalone=\"");
298 if (document.xmlStandalone())
299 result.appendLiteral("yes");
300 else
301 result.appendLiteral("no");
302 }
303
304 result.appendLiteral("\"?>");
305 } 150 }
306 151
307 void MarkupAccumulator::appendDocumentType(StringBuilder& result, const Document Type& n) 152 void MarkupAccumulator::appendDocumentType(StringBuilder& result, const Document Type& n)
308 { 153 {
309 if (n.name().isEmpty()) 154 m_formatter.appendDocumentType(result, n);
310 return;
311
312 result.appendLiteral("<!DOCTYPE ");
313 result.append(n.name());
314 if (!n.publicId().isEmpty()) {
315 result.appendLiteral(" PUBLIC \"");
316 result.append(n.publicId());
317 result.append('"');
318 if (!n.systemId().isEmpty()) {
319 result.appendLiteral(" \"");
320 result.append(n.systemId());
321 result.append('"');
322 }
323 } else if (!n.systemId().isEmpty()) {
324 result.appendLiteral(" SYSTEM \"");
325 result.append(n.systemId());
326 result.append('"');
327 }
328 result.append('>');
329 } 155 }
330 156
331 void MarkupAccumulator::appendProcessingInstruction(StringBuilder& result, const String& target, const String& data) 157 void MarkupAccumulator::appendProcessingInstruction(StringBuilder& result, const String& target, const String& data)
332 { 158 {
333 // FIXME: PI data is not escaped, but XMLSerializer (and possibly other call ers) this should raise an exception if it includes "?>". 159 m_formatter.appendProcessingInstruction(result, target, data);
334 result.appendLiteral("<?");
335 result.append(target);
336 result.append(' ');
337 result.append(data);
338 result.appendLiteral("?>");
339 } 160 }
340 161
341 bool MarkupAccumulator::shouldIgnoreAttribute(const Attribute& attribute) 162 bool MarkupAccumulator::shouldIgnoreAttribute(const Attribute& attribute)
342 { 163 {
343 return false; 164 return false;
344 } 165 }
345 166
346 void MarkupAccumulator::appendElement(StringBuilder& result, Element& element, N amespaces* namespaces) 167 void MarkupAccumulator::appendElement(StringBuilder& result, Element& element, N amespaces* namespaces)
347 { 168 {
348 appendOpenTag(result, element, namespaces); 169 appendOpenTag(result, element, namespaces);
349 170
350 AttributeCollection attributes = element.attributes(); 171 AttributeCollection attributes = element.attributes();
351 for (const auto& attribute : attributes) { 172 for (const auto& attribute : attributes) {
352 if (!shouldIgnoreAttribute(attribute)) 173 if (!shouldIgnoreAttribute(attribute))
353 appendAttribute(result, element, attribute, namespaces); 174 appendAttribute(result, element, attribute, namespaces);
354 } 175 }
355 176
356 // Give an opportunity to subclasses to add their own attributes. 177 // Give an opportunity to subclasses to add their own attributes.
357 appendCustomAttributes(result, element, namespaces); 178 appendCustomAttributes(result, element, namespaces);
358 179
359 appendCloseTag(result, element); 180 appendCloseTag(result, element);
360 } 181 }
361 182
362 void MarkupAccumulator::appendOpenTag(StringBuilder& result, const Element& elem ent, Namespaces* namespaces) 183 void MarkupAccumulator::appendOpenTag(StringBuilder& result, const Element& elem ent, Namespaces* namespaces)
363 { 184 {
364 result.append('<'); 185 m_formatter.appendOpenTag(result, element, namespaces);
365 result.append(element.tagQName().toString());
366 if (!serializeAsHTMLDocument(element) && namespaces && shouldAddNamespaceEle ment(element, *namespaces))
367 appendNamespace(result, element.prefix(), element.namespaceURI(), *names paces);
368 } 186 }
369 187
370 void MarkupAccumulator::appendCloseTag(StringBuilder& result, const Element& ele ment) 188 void MarkupAccumulator::appendCloseTag(StringBuilder& result, const Element& ele ment)
371 { 189 {
372 if (shouldSelfClose(element)) { 190 m_formatter.appendCloseTag(result, element);
373 if (element.isHTMLElement())
374 result.append(' '); // XHTML 1.0 <-> HTML compatibility.
375 result.append('/');
376 }
377 result.append('>');
378 }
379
380 static inline bool attributeIsInSerializedNamespace(const Attribute& attribute)
381 {
382 return attribute.namespaceURI() == XMLNames::xmlNamespaceURI
383 || attribute.namespaceURI() == XLinkNames::xlinkNamespaceURI
384 || attribute.namespaceURI() == XMLNSNames::xmlnsNamespaceURI;
385 } 191 }
386 192
387 void MarkupAccumulator::appendAttribute(StringBuilder& result, const Element& el ement, const Attribute& attribute, Namespaces* namespaces) 193 void MarkupAccumulator::appendAttribute(StringBuilder& result, const Element& el ement, const Attribute& attribute, Namespaces* namespaces)
388 { 194 {
389 bool documentIsHTML = serializeAsHTMLDocument(element); 195 m_formatter.appendAttribute(result, element, attribute, namespaces);
390
391 QualifiedName prefixedName = attribute.name();
392 if (documentIsHTML && !attributeIsInSerializedNamespace(attribute)) {
393 result.append(' ');
394 result.append(attribute.name().localName());
395 } else {
396 if (attribute.namespaceURI() == XMLNSNames::xmlnsNamespaceURI) {
397 if (!attribute.prefix() && attribute.localName() != xmlnsAtom)
398 prefixedName.setPrefix(xmlnsAtom);
399 if (namespaces) { // Account for the namespace attribute we're about to append.
400 const AtomicString& lookupKey = (!attribute.prefix()) ? emptyAto m : attribute.localName();
401 namespaces->set(lookupKey, attribute.value());
402 }
403 } else if (attribute.namespaceURI() == XMLNames::xmlNamespaceURI) {
404 if (!attribute.prefix())
405 prefixedName.setPrefix(xmlAtom);
406 } else {
407 if (attribute.namespaceURI() == XLinkNames::xlinkNamespaceURI) {
408 if (!attribute.prefix())
409 prefixedName.setPrefix(xlinkAtom);
410 }
411
412 if (namespaces && shouldAddNamespaceAttribute(attribute, element)) {
413 if (!prefixedName.prefix()) {
414 // This behavior is in process of being standardized. See cr bug.com/248044 and https://www.w3.org/Bugs/Public/show_bug.cgi?id=24208
415 String prefixPrefix("ns", 2);
416 for (unsigned i = attribute.namespaceURI().impl()->existingH ash(); ; ++i) {
417 AtomicString newPrefix(String(prefixPrefix + String::num ber(i)));
418 AtomicString foundURI = namespaces->get(newPrefix);
419 if (foundURI == attribute.namespaceURI() || foundURI == nullAtom) {
420 // We already generated a prefix for this namespace.
421 prefixedName.setPrefix(newPrefix);
422 break;
423 }
424 }
425 }
426 ASSERT(prefixedName.prefix());
427 appendNamespace(result, prefixedName.prefix(), attribute.namespa ceURI(), *namespaces);
428 }
429 }
430 result.append(' ');
431 result.append(prefixedName.toString());
432 }
433
434 result.append('=');
435
436 if (element.isURLAttribute(attribute)) {
437 appendQuotedURLAttributeValue(result, element, attribute);
438 } else {
439 result.append('"');
440 appendAttributeValue(result, attribute.value(), documentIsHTML);
441 result.append('"');
442 }
443 } 196 }
444 197
445 void MarkupAccumulator::appendCDATASection(StringBuilder& result, const String& section) 198 void MarkupAccumulator::appendCDATASection(StringBuilder& result, const String& section)
446 { 199 {
447 // FIXME: CDATA content is not escaped, but XMLSerializer (and possibly othe r callers) should raise an exception if it includes "]]>". 200 m_formatter.appendCDATASection(result, section);
448 result.appendLiteral("<![CDATA[");
449 result.append(section);
450 result.appendLiteral("]]>");
451 } 201 }
452 202
453 bool MarkupAccumulator::shouldAddNamespaceElement(const Element& element, Namesp aces& namespaces) const 203 bool MarkupAccumulator::shouldAddNamespaceElement(const Element& element, Namesp aces& namespaces) const
454 { 204 {
455 // Don't add namespace attribute if it is already defined for this elem. 205 return m_formatter.shouldAddNamespaceElement(element, namespaces);
456 const AtomicString& prefix = element.prefix();
457 if (prefix.isEmpty()) {
458 if (element.hasAttribute(xmlnsAtom)) {
459 namespaces.set(emptyAtom, element.namespaceURI());
460 return false;
461 }
462 return true;
463 }
464
465 return !element.hasAttribute(WTF::xmlnsWithColon + prefix);
466 } 206 }
467 207
468 bool MarkupAccumulator::shouldAddNamespaceAttribute(const Attribute& attribute, const Element& element) const 208 bool MarkupAccumulator::shouldAddNamespaceAttribute(const Attribute& attribute, const Element& element) const
469 { 209 {
470 // xmlns and xmlns:prefix attributes should be handled by another branch in appendAttribute. 210 return m_formatter.shouldAddNamespaceAttribute(attribute, element);
471 ASSERT(attribute.namespaceURI() != XMLNSNames::xmlnsNamespaceURI);
472
473 // Attributes are in the null namespace by default.
474 if (!attribute.namespaceURI())
475 return false;
476
477 // Attributes without a prefix will need one generated for them, and an xmln s attribute for that prefix.
478 if (!attribute.prefix())
479 return true;
480
481 return !element.hasAttribute(WTF::xmlnsWithColon + attribute.prefix());
482 } 211 }
483 212
484 EntityMask MarkupAccumulator::entityMaskForText(const Text& text) const 213 EntityMask MarkupAccumulator::entityMaskForText(const Text& text) const
485 { 214 {
486 if (!serializeAsHTMLDocument(text)) 215 return m_formatter.entityMaskForText(text);
487 return EntityMaskInPCDATA;
488
489 // TODO(hajimehoshi): We need to switch EditingStrategy.
490 const QualifiedName* parentName = nullptr;
491 if (text.parentElement())
492 parentName = &(text.parentElement())->tagQName();
493
494 if (parentName && (*parentName == scriptTag || *parentName == styleTag || *p arentName == xmpTag))
495 return EntityMaskInCDATA;
496 return EntityMaskInHTMLPCDATA;
497 } 216 }
498 217
499 // Rules of self-closure
500 // 1. No elements in HTML documents use the self-closing syntax.
501 // 2. Elements w/ children never self-close because they use a separate end tag.
502 // 3. HTML elements which do not have a "forbidden" end tag will close with a se parate end tag.
503 // 4. Other elements self-close.
504 bool MarkupAccumulator::shouldSelfClose(const Element& element) const 218 bool MarkupAccumulator::shouldSelfClose(const Element& element) const
505 { 219 {
506 if (serializeAsHTMLDocument(element)) 220 return m_formatter.shouldSelfClose(element);
507 return false;
508 if (element.hasChildren())
509 return false;
510 if (element.isHTMLElement() && !elementCannotHaveEndTag(element))
511 return false;
512 return true;
513 } 221 }
514 222
515 bool MarkupAccumulator::serializeAsHTMLDocument(const Node& node) const 223 bool MarkupAccumulator::serializeAsHTMLDocument(const Node& node) const
516 { 224 {
517 if (m_serializationType == SerializationType::ForcedXML) 225 return m_formatter.serializeAsHTMLDocument(node);
518 return false;
519 return node.document().isHTMLDocument();
520 } 226 }
521 227
522 template<typename Strategy> 228 template<typename Strategy>
523 static void serializeNodesWithNamespaces(MarkupAccumulator& accumulator, Node& t argetNode, EChildrenOnly childrenOnly, const Namespaces* namespaces) 229 static void serializeNodesWithNamespaces(MarkupAccumulator& accumulator, Node& t argetNode, EChildrenOnly childrenOnly, const Namespaces* namespaces)
524 { 230 {
525 Namespaces namespaceHash; 231 Namespaces namespaceHash;
526 if (namespaces) 232 if (namespaces)
527 namespaceHash = *namespaces; 233 namespaceHash = *namespaces;
528 234
529 if (!childrenOnly) 235 if (!childrenOnly)
(...skipping 20 matching lines...) Expand all
550 namespaces = &namespaceHash; 256 namespaces = &namespaceHash;
551 } 257 }
552 258
553 serializeNodesWithNamespaces<Strategy>(accumulator, targetNode, childrenOnly , namespaces); 259 serializeNodesWithNamespaces<Strategy>(accumulator, targetNode, childrenOnly , namespaces);
554 return accumulator.toString(); 260 return accumulator.toString();
555 } 261 }
556 262
557 template String serializeNodes<EditingStrategy>(MarkupAccumulator&, Node&, EChil drenOnly); 263 template String serializeNodes<EditingStrategy>(MarkupAccumulator&, Node&, EChil drenOnly);
558 264
559 } 265 }
OLDNEW
« no previous file with comments | « Source/core/editing/MarkupAccumulator.h ('k') | Source/core/editing/MarkupFormatter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698