Chromium Code Reviews| 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 |