OLD | NEW |
---|---|
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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 if (toElement(targetNode).hasTagName(tagNamesToSkip->at(i))) | 130 if (toElement(targetNode).hasTagName(tagNamesToSkip->at(i))) |
131 return; | 131 return; |
132 } | 132 } |
133 } | 133 } |
134 | 134 |
135 Namespaces namespaceHash; | 135 Namespaces namespaceHash; |
136 if (namespaces) | 136 if (namespaces) |
137 namespaceHash = *namespaces; | 137 namespaceHash = *namespaces; |
138 | 138 |
139 if (!childrenOnly) | 139 if (!childrenOnly) |
140 appendStartTag(targetNode, &namespaceHash); | 140 appendStartTag(targetNode, &namespaceHash); |
yosin_UTC9
2014/08/01 02:27:14
We may want to pass |Element*| to |appendStartTag|
Inactive
2014/08/01 04:08:12
I actually had the same idea but had to revert tha
| |
141 | 141 |
142 if (!(serializeAsHTMLDocument(targetNode) && elementCannotHaveEndTag(targetN ode))) { | 142 if (!(serializeAsHTMLDocument(targetNode) && elementCannotHaveEndTag(targetN ode))) { |
143 Node* current = isHTMLTemplateElement(targetNode) ? toHTMLTemplateElemen t(targetNode).content()->firstChild() : targetNode.firstChild(); | 143 Node* current = isHTMLTemplateElement(targetNode) ? toHTMLTemplateElemen t(targetNode).content()->firstChild() : targetNode.firstChild(); |
144 for ( ; current; current = current->nextSibling()) | 144 for ( ; current; current = current->nextSibling()) |
145 serializeNodesWithNamespaces(*current, IncludeNode, &namespaceHash, tagNamesToSkip); | 145 serializeNodesWithNamespaces(*current, IncludeNode, &namespaceHash, tagNamesToSkip); |
146 } | 146 } |
147 | 147 |
148 if (!childrenOnly) | 148 if (!childrenOnly && targetNode.isElementNode()) |
149 appendEndTag(targetNode); | 149 appendEndTag(toElement(targetNode)); |
yosin_UTC9
2014/08/01 02:27:14
Good catch!
| |
150 } | 150 } |
151 | 151 |
152 String MarkupAccumulator::resolveURLIfNeeded(const Element& element, const Strin g& urlString) const | 152 String MarkupAccumulator::resolveURLIfNeeded(const Element& element, const Strin g& urlString) const |
153 { | 153 { |
154 switch (m_resolveURLsMethod) { | 154 switch (m_resolveURLsMethod) { |
155 case ResolveAllURLs: | 155 case ResolveAllURLs: |
156 return element.document().completeURL(urlString).string(); | 156 return element.document().completeURL(urlString).string(); |
157 | 157 |
158 case ResolveNonLocalURLs: | 158 case ResolveNonLocalURLs: |
159 if (!element.document().url().isLocalFile()) | 159 if (!element.document().url().isLocalFile()) |
(...skipping 11 matching lines...) Expand all Loading... | |
171 m_markup.append(string); | 171 m_markup.append(string); |
172 } | 172 } |
173 | 173 |
174 void MarkupAccumulator::appendStartTag(Node& node, Namespaces* namespaces) | 174 void MarkupAccumulator::appendStartTag(Node& node, Namespaces* namespaces) |
175 { | 175 { |
176 appendStartMarkup(m_markup, node, namespaces); | 176 appendStartMarkup(m_markup, node, namespaces); |
177 if (m_nodes) | 177 if (m_nodes) |
178 m_nodes->append(&node); | 178 m_nodes->append(&node); |
179 } | 179 } |
180 | 180 |
181 void MarkupAccumulator::appendEndTag(const Node& node) | 181 void MarkupAccumulator::appendEndTag(const Element& element) |
182 { | 182 { |
183 appendEndMarkup(m_markup, node); | 183 appendEndMarkup(m_markup, element); |
184 } | 184 } |
185 | 185 |
186 size_t MarkupAccumulator::totalLength(const Vector<String>& strings) | 186 size_t MarkupAccumulator::totalLength(const Vector<String>& strings) |
187 { | 187 { |
188 size_t length = 0; | 188 size_t length = 0; |
189 for (size_t i = 0; i < strings.size(); ++i) | 189 for (size_t i = 0; i < strings.size(); ++i) |
190 length += strings[i].length(); | 190 length += strings[i].length(); |
191 return length; | 191 return length; |
192 } | 192 } |
193 | 193 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
391 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) | 391 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) |
392 appendAttribute(result, element, *it, namespaces); | 392 appendAttribute(result, element, *it, namespaces); |
393 } | 393 } |
394 | 394 |
395 // Give an opportunity to subclasses to add their own attributes. | 395 // Give an opportunity to subclasses to add their own attributes. |
396 appendCustomAttributes(result, element, namespaces); | 396 appendCustomAttributes(result, element, namespaces); |
397 | 397 |
398 appendCloseTag(result, element); | 398 appendCloseTag(result, element); |
399 } | 399 } |
400 | 400 |
401 static String nodeNamePreservingCase(const Element& element) | |
402 { | |
403 return element.tagQName().toString(); | |
404 } | |
405 | |
406 void MarkupAccumulator::appendOpenTag(StringBuilder& result, const Element& elem ent, Namespaces* namespaces) | 401 void MarkupAccumulator::appendOpenTag(StringBuilder& result, const Element& elem ent, Namespaces* namespaces) |
407 { | 402 { |
408 result.append('<'); | 403 result.append('<'); |
409 result.append(nodeNamePreservingCase(element)); | 404 result.append(element.tagQName().toString()); |
410 if (!serializeAsHTMLDocument(element) && namespaces && shouldAddNamespaceEle ment(element, *namespaces)) | 405 if (!serializeAsHTMLDocument(element) && namespaces && shouldAddNamespaceEle ment(element, *namespaces)) |
411 appendNamespace(result, element.prefix(), element.namespaceURI(), *names paces); | 406 appendNamespace(result, element.prefix(), element.namespaceURI(), *names paces); |
412 } | 407 } |
413 | 408 |
414 void MarkupAccumulator::appendCloseTag(StringBuilder& result, const Element& ele ment) | 409 void MarkupAccumulator::appendCloseTag(StringBuilder& result, const Element& ele ment) |
415 { | 410 { |
416 if (shouldSelfClose(element)) { | 411 if (shouldSelfClose(element)) { |
417 if (element.isHTMLElement()) | 412 if (element.isHTMLElement()) |
418 result.append(' '); // XHTML 1.0 <-> HTML compatibility. | 413 result.append(' '); // XHTML 1.0 <-> HTML compatibility. |
419 result.append('/'); | 414 result.append('/'); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
520 ASSERT_NOT_REACHED(); | 515 ASSERT_NOT_REACHED(); |
521 break; | 516 break; |
522 } | 517 } |
523 } | 518 } |
524 | 519 |
525 // Rules of self-closure | 520 // Rules of self-closure |
526 // 1. No elements in HTML documents use the self-closing syntax. | 521 // 1. No elements in HTML documents use the self-closing syntax. |
527 // 2. Elements w/ children never self-close because they use a separate end tag. | 522 // 2. Elements w/ children never self-close because they use a separate end tag. |
528 // 3. HTML elements which do not have a "forbidden" end tag will close with a se parate end tag. | 523 // 3. HTML elements which do not have a "forbidden" end tag will close with a se parate end tag. |
529 // 4. Other elements self-close. | 524 // 4. Other elements self-close. |
530 bool MarkupAccumulator::shouldSelfClose(const Node& node) | 525 bool MarkupAccumulator::shouldSelfClose(const Element& element) |
531 { | 526 { |
532 if (serializeAsHTMLDocument(node)) | 527 if (serializeAsHTMLDocument(element)) |
533 return false; | 528 return false; |
534 if (node.hasChildren()) | 529 if (element.hasChildren()) |
535 return false; | 530 return false; |
536 if (node.isHTMLElement() && !elementCannotHaveEndTag(node)) | 531 if (element.isHTMLElement() && !elementCannotHaveEndTag(element)) |
537 return false; | 532 return false; |
538 return true; | 533 return true; |
539 } | 534 } |
540 | 535 |
541 bool MarkupAccumulator::elementCannotHaveEndTag(const Node& node) | 536 bool MarkupAccumulator::elementCannotHaveEndTag(const Node& node) |
542 { | 537 { |
543 if (!node.isHTMLElement()) | 538 if (!node.isHTMLElement()) |
544 return false; | 539 return false; |
545 | 540 |
546 // FIXME: ieForbidsInsertHTML may not be the right function to call here | 541 // FIXME: ieForbidsInsertHTML may not be the right function to call here |
547 // ieForbidsInsertHTML is used to disallow setting innerHTML/outerHTML | 542 // ieForbidsInsertHTML is used to disallow setting innerHTML/outerHTML |
548 // or createContextualFragment. It does not necessarily align with | 543 // or createContextualFragment. It does not necessarily align with |
549 // which elements should be serialized w/o end tags. | 544 // which elements should be serialized w/o end tags. |
550 return toHTMLElement(node).ieForbidsInsertHTML(); | 545 return toHTMLElement(node).ieForbidsInsertHTML(); |
551 } | 546 } |
552 | 547 |
553 void MarkupAccumulator::appendEndMarkup(StringBuilder& result, const Node& node) | 548 void MarkupAccumulator::appendEndMarkup(StringBuilder& result, const Element& el ement) |
554 { | 549 { |
555 if (!node.isElementNode() || shouldSelfClose(node) || (!node.hasChildren() & & elementCannotHaveEndTag(node))) | 550 if (shouldSelfClose(element) || (!element.hasChildren() && elementCannotHave EndTag(element))) |
556 return; | 551 return; |
557 | 552 |
558 result.appendLiteral("</"); | 553 result.appendLiteral("</"); |
559 result.append(nodeNamePreservingCase(toElement(node))); | 554 result.append(element.tagQName().toString()); |
560 result.append('>'); | 555 result.append('>'); |
561 } | 556 } |
562 | 557 |
563 bool MarkupAccumulator::serializeAsHTMLDocument(const Node& node) const | 558 bool MarkupAccumulator::serializeAsHTMLDocument(const Node& node) const |
564 { | 559 { |
565 if (m_serializationType == ForcedXML) | 560 if (m_serializationType == ForcedXML) |
566 return false; | 561 return false; |
567 return node.document().isHTMLDocument(); | 562 return node.document().isHTMLDocument(); |
568 } | 563 } |
569 | 564 |
570 } | 565 } |
OLD | NEW |