Changeset 65854 in webkit


Ignore:
Timestamp:
Aug 23, 2010 7:14:02 PM (14 years ago)
Author:
rniwa@webkit.org
Message:

2010-08-23 Ryosuke Niwa <rniwa@webkit.org>

Reviewed by Eric Seidel.

MarkupAccumulator::appendStartMarkup should be broken down into pieces
https://bugs.webkit.org/show_bug.cgi?id=44288

Extracted appendText, appendComment, appendProcessingInstruction, appendElement and appendCDATASection.
Also simplified the conditionals in appendText.

No new tests are added since this is a cleanup.

  • editing/markup.cpp: (WebCore::MarkupAccumulator::appendText): (WebCore::MarkupAccumulator::appendComment): (WebCore::MarkupAccumulator::appendProcessingInstruction): (WebCore::MarkupAccumulator::appendElement): (WebCore::MarkupAccumulator::appendCDATASection): (WebCore::MarkupAccumulator::appendStartMarkup):
Location:
trunk/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r65853 r65854  
     12010-08-23  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        MarkupAccumulator::appendStartMarkup should be broken down into pieces
     6        https://bugs.webkit.org/show_bug.cgi?id=44288
     7
     8        Extracted appendText, appendComment, appendProcessingInstruction, appendElement and appendCDATASection.
     9        Also simplified the conditionals in appendText.
     10
     11        No new tests are added since this is a cleanup.
     12
     13        * editing/markup.cpp:
     14        (WebCore::MarkupAccumulator::appendText):
     15        (WebCore::MarkupAccumulator::appendComment):
     16        (WebCore::MarkupAccumulator::appendProcessingInstruction):
     17        (WebCore::MarkupAccumulator::appendElement):
     18        (WebCore::MarkupAccumulator::appendCDATASection):
     19        (WebCore::MarkupAccumulator::appendStartMarkup):
     20
    1212010-08-23  Simon Fraser  <simon.fraser@apple.com>
    222
  • trunk/WebCore/editing/markup.cpp

    r65845 r65854  
    124124    bool shouldAddNamespaceAttribute(const Attribute*, Namespaces&);
    125125    void appendNamespace(Vector<UChar>& result, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces&);
     126    void appendText(Vector<UChar>& out, Text*);
     127    void appendComment(Vector<UChar>& out, const String& comment);
    126128    void appendDocumentType(Vector<UChar>& result, const DocumentType*);
     129    void appendProcessingInstruction(Vector<UChar>& out, const String& target, const String& data);
    127130    void removeExteriorStyles(CSSMutableStyleDeclaration*);
     131    void appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, Namespaces*, RangeFullySelectsNode);
     132    void appendCDATASection(Vector<UChar>& out, const String& section);
    128133    void appendStartMarkup(Vector<UChar>& result, const Node*, bool convertBlocksToInlines, Namespaces*, RangeFullySelectsNode);
    129134    bool shouldSelfClose(const Node*);
     
    481486}
    482487
     488void MarkupAccumulator::appendText(Vector<UChar>& out, Text* text)
     489{
     490    const QualifiedName* parentName = 0;
     491    if (text->parentElement())
     492        parentName = &static_cast<Element*>(text->parentElement())->tagQName();
     493
     494    if (parentName && (*parentName == scriptTag || *parentName == styleTag || *parentName == xmpTag)) {
     495        appendUCharRange(out, ucharRange(text, m_range));
     496        return;
     497    }
     498
     499    if (!shouldAnnotate() || (parentName && *parentName == textareaTag)) {
     500        appendEscapedContent(out, ucharRange(text, m_range), text->document()->isHTMLDocument());
     501        return;
     502    }
     503
     504    bool useRenderedText = !enclosingNodeWithTag(Position(text, 0), selectTag);
     505    String markup = escapeContentText(useRenderedText ? renderedText(text, m_range) : stringValueForRange(text, m_range), false);
     506    markup = convertHTMLTextToInterchangeFormat(markup, text);
     507    append(out, markup);
     508}
     509
     510void MarkupAccumulator::appendComment(Vector<UChar>& out, const String& comment)
     511{
     512    // FIXME: Comment content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "-->".
     513    append(out, "<!--");
     514    append(out, comment);
     515    append(out, "-->");
     516}
     517
    483518void MarkupAccumulator::appendDocumentType(Vector<UChar>& result, const DocumentType* n)
    484519{
     
    510545}
    511546
     547void MarkupAccumulator::appendProcessingInstruction(Vector<UChar>& out, const String& target, const String& data)
     548{
     549    // FIXME: PI data is not escaped, but XMLSerializer (and possibly other callers) this should raise an exception if it includes "?>".
     550    append(out, "<?");
     551    append(out, target);
     552    append(out, " ");
     553    append(out, data);
     554    append(out, "?>");
     555}
     556
    512557void MarkupAccumulator::removeExteriorStyles(CSSMutableStyleDeclaration* style)
    513558{
    514559    style->removeProperty(CSSPropertyFloat);
     560}
     561
     562void MarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, Namespaces* namespaces, RangeFullySelectsNode rangeFullySelectsNode)
     563{
     564    bool documentIsHTML = element->document()->isHTMLDocument();
     565    out.append('<');
     566    append(out, element->nodeNamePreservingCase());
     567    if (!documentIsHTML && namespaces && shouldAddNamespaceElement(element))
     568        appendNamespace(out, element->prefix(), element->namespaceURI(), *namespaces);
     569
     570    NamedNodeMap* attributes = element->attributes();
     571    unsigned length = attributes->length();
     572    for (unsigned int i = 0; i < length; i++) {
     573        Attribute* attribute = attributes->attributeItem(i);
     574        // We'll handle the style attribute separately, below.
     575        if (attribute->name() == styleAttr && element->isHTMLElement() && (shouldAnnotate() || addDisplayInline))
     576            continue;
     577        out.append(' ');
     578       
     579        if (documentIsHTML)
     580            append(out, attribute->name().localName());
     581        else
     582            append(out, attribute->name().toString());
     583
     584        out.append('=');
     585
     586        if (element->isURLAttribute(attribute)) {
     587            // We don't want to complete file:/// URLs because it may contain sensitive information
     588            // about the user's system.
     589            if (shouldResolveURLs() && !element->document()->url().isLocalFile())
     590                appendQuotedURLAttributeValue(out, element->document()->completeURL(attribute->value()).string());
     591            else
     592                appendQuotedURLAttributeValue(out, attribute->value().string());
     593        } else {
     594            out.append('\"');
     595            appendAttributeValue(out, attribute->value(), documentIsHTML);
     596            out.append('\"');
     597        }
     598
     599        if (!documentIsHTML && namespaces && shouldAddNamespaceAttribute(attribute, *namespaces))
     600            appendNamespace(out, attribute->prefix(), attribute->namespaceURI(), *namespaces);
     601    }
     602
     603    if (element->isHTMLElement() && (shouldAnnotate() || addDisplayInline)) {
     604        RefPtr<CSSMutableStyleDeclaration> style = static_cast<HTMLElement*>(element)->getInlineStyleDecl()->copy();
     605        if (shouldAnnotate()) {
     606            RefPtr<CSSMutableStyleDeclaration> styleFromMatchedRules = styleFromMatchedRulesForElement(const_cast<Element*>(element));
     607            // Styles from the inline style declaration, held in the variable "style", take precedence
     608            // over those from matched rules.
     609            styleFromMatchedRules->merge(style.get());
     610            style = styleFromMatchedRules;
     611
     612            RefPtr<CSSComputedStyleDeclaration> computedStyleForElement = computedStyle(element);
     613            RefPtr<CSSMutableStyleDeclaration> fromComputedStyle = CSSMutableStyleDeclaration::create();
     614
     615            {
     616                CSSMutableStyleDeclaration::const_iterator end = style->end();
     617                for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {
     618                    const CSSProperty& property = *it;
     619                    CSSValue* value = property.value();
     620                    // The property value, if it's a percentage, may not reflect the actual computed value. 
     621                    // For example: style="height: 1%; overflow: visible;" in quirksmode
     622                    // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot copy/paste fidelity problem
     623                    if (value->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
     624                        if (static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
     625                            if (RefPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
     626                                fromComputedStyle->addParsedProperty(CSSProperty(property.id(), computedPropertyValue));
     627                }
     628            }
     629            style->merge(fromComputedStyle.get());
     630        }
     631        if (addDisplayInline)
     632            style->setProperty(CSSPropertyDisplay, CSSValueInline, true);
     633        // If the node is not fully selected by the range, then we don't want to keep styles that affect its relationship to the nodes around it
     634        // only the ones that affect it and the nodes within it.
     635        if (rangeFullySelectsNode == DoesNotFullySelectNode)
     636            removeExteriorStyles(style.get());
     637        if (style->length() > 0) {
     638            DEFINE_STATIC_LOCAL(const String, stylePrefix, (" style=\""));
     639            append(out, stylePrefix);
     640            appendAttributeValue(out, style->cssText(), documentIsHTML);
     641            out.append('\"');
     642        }
     643    }
     644
     645    if (shouldSelfClose(element)) {
     646        if (element->isHTMLElement())
     647            out.append(' '); // XHTML 1.0 <-> HTML compatibility.
     648        out.append('/');
     649    }
     650    out.append('>');
     651}
     652
     653void MarkupAccumulator::appendCDATASection(Vector<UChar>& out, const String& section)
     654{
     655    // FIXME: CDATA content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "]]>".
     656    append(out, "<![CDATA[");
     657    append(out, section);
     658    append(out, "]]>");
    515659}
    516660
     
    520664        namespaces->checkConsistency();
    521665
    522     bool documentIsHTML = node->document()->isHTMLDocument();
    523666    switch (node->nodeType()) {
    524     case Node::TEXT_NODE: {
    525         if (Node* parent = node->parentNode()) {
    526             if (parent->hasTagName(scriptTag)
    527                 || parent->hasTagName(styleTag)
    528                 || parent->hasTagName(xmpTag)) {
    529                 appendUCharRange(result, ucharRange(node, m_range));
    530                 break;
    531             }
    532             if (parent->hasTagName(textareaTag)) {
    533                 appendEscapedContent(result, ucharRange(node, m_range), documentIsHTML);
    534                 break;
    535             }
    536         }
    537         if (shouldAnnotate()) {
    538             bool useRenderedText = !enclosingNodeWithTag(Position(const_cast<Node*>(node), 0), selectTag);
    539             String markup = escapeContentText(useRenderedText ? renderedText(node, m_range) : stringValueForRange(node, m_range), false);
    540             markup = convertHTMLTextToInterchangeFormat(markup, static_cast<const Text*>(node));
    541             append(result, markup);
    542             break;
    543         }
    544         appendEscapedContent(result, ucharRange(node, m_range), documentIsHTML);
     667    case Node::TEXT_NODE:
     668        appendText(result, static_cast<Text*>(const_cast<Node*>(node)));
    545669        break;
    546     }
    547670    case Node::COMMENT_NODE:
    548         // FIXME: Comment content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "-->".
    549         append(result, "<!--");
    550         append(result, static_cast<const Comment*>(node)->data());
    551         append(result, "-->");
     671        appendComment(result, static_cast<const Comment*>(node)->data());
    552672        break;
    553673    case Node::DOCUMENT_NODE:
     
    557677        appendDocumentType(result, static_cast<const DocumentType*>(node));
    558678        break;
    559     case Node::PROCESSING_INSTRUCTION_NODE: {
    560         // FIXME: PI data is not escaped, but XMLSerializer (and possibly other callers) this should raise an exception if it includes "?>".
    561         const ProcessingInstruction* n = static_cast<const ProcessingInstruction*>(node);
    562         append(result, "<?");
    563         append(result, n->target());
    564         append(result, " ");
    565         append(result, n->data());
    566         append(result, "?>");
     679    case Node::PROCESSING_INSTRUCTION_NODE:
     680        appendProcessingInstruction(result, static_cast<const ProcessingInstruction*>(node)->target(), static_cast<const ProcessingInstruction*>(node)->data());
    567681        break;
    568     }
    569     case Node::ELEMENT_NODE: {
    570         result.append('<');
    571         Element* element = const_cast<Element*>(static_cast<const Element*>(node));
    572         bool convert = convertBlocksToInlines && isBlock(const_cast<Node*>(node));
    573         append(result, element->nodeNamePreservingCase());
    574         if (!documentIsHTML && namespaces && shouldAddNamespaceElement(element))
    575             appendNamespace(result, element->prefix(), element->namespaceURI(), *namespaces);
    576 
    577         NamedNodeMap* attributes = element->attributes();
    578         unsigned length = attributes->length();
    579         for (unsigned int i = 0; i < length; i++) {
    580             Attribute* attribute = attributes->attributeItem(i);
    581             // We'll handle the style attribute separately, below.
    582             if (attribute->name() == styleAttr && element->isHTMLElement() && (shouldAnnotate() || convert))
    583                 continue;
    584             result.append(' ');
    585 
    586             if (documentIsHTML)
    587                 append(result, attribute->name().localName());
    588             else
    589                 append(result, attribute->name().toString());
    590 
    591             result.append('=');
    592 
    593             if (element->isURLAttribute(attribute)) {
    594                 // We don't want to complete file:/// URLs because it may contain sensitive information
    595                 // about the user's system.
    596                 if (shouldResolveURLs() && !node->document()->url().isLocalFile())
    597                     appendQuotedURLAttributeValue(result, node->document()->completeURL(attribute->value()).string());
    598                 else
    599                     appendQuotedURLAttributeValue(result, attribute->value().string());
    600             } else {
    601                 result.append('\"');
    602                 appendAttributeValue(result, attribute->value(), documentIsHTML);
    603                 result.append('\"');
    604             }
    605 
    606             if (!documentIsHTML && namespaces && shouldAddNamespaceAttribute(attribute, *namespaces))
    607                 appendNamespace(result, attribute->prefix(), attribute->namespaceURI(), *namespaces);
    608         }
    609 
    610         if (element->isHTMLElement() && (shouldAnnotate() || convert)) {
    611             RefPtr<CSSMutableStyleDeclaration> style = static_cast<HTMLElement*>(element)->getInlineStyleDecl()->copy();
    612             if (shouldAnnotate()) {
    613                 RefPtr<CSSMutableStyleDeclaration> styleFromMatchedRules = styleFromMatchedRulesForElement(const_cast<Element*>(element));
    614                 // Styles from the inline style declaration, held in the variable "style", take precedence
    615                 // over those from matched rules.
    616                 styleFromMatchedRules->merge(style.get());
    617                 style = styleFromMatchedRules;
    618 
    619                 RefPtr<CSSComputedStyleDeclaration> computedStyleForElement = computedStyle(element);
    620                 RefPtr<CSSMutableStyleDeclaration> fromComputedStyle = CSSMutableStyleDeclaration::create();
    621 
    622                 {
    623                     CSSMutableStyleDeclaration::const_iterator end = style->end();
    624                     for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {
    625                         const CSSProperty& property = *it;
    626                         CSSValue* value = property.value();
    627                         // The property value, if it's a percentage, may not reflect the actual computed value. 
    628                         // For example: style="height: 1%; overflow: visible;" in quirksmode
    629                         // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot copy/paste fidelity problem
    630                         if (value->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
    631                             if (static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
    632                                 if (RefPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
    633                                     fromComputedStyle->addParsedProperty(CSSProperty(property.id(), computedPropertyValue));
    634                     }
    635                 }
    636                 style->merge(fromComputedStyle.get());
    637             }
    638             if (convert)
    639                 style->setProperty(CSSPropertyDisplay, CSSValueInline, true);
    640             // If the node is not fully selected by the range, then we don't want to keep styles that affect its relationship to the nodes around it
    641             // only the ones that affect it and the nodes within it.
    642             if (rangeFullySelectsNode == DoesNotFullySelectNode)
    643                 removeExteriorStyles(style.get());
    644             if (style->length() > 0) {
    645                 DEFINE_STATIC_LOCAL(const String, stylePrefix, (" style=\""));
    646                 append(result, stylePrefix);
    647                 appendAttributeValue(result, style->cssText(), documentIsHTML);
    648                 result.append('\"');
    649             }
    650         }
    651 
    652         if (shouldSelfClose(element)) {
    653             if (element->isHTMLElement())
    654                 result.append(' '); // XHTML 1.0 <-> HTML compatibility.
    655             result.append('/');
    656         }
    657         result.append('>');
     682    case Node::ELEMENT_NODE:
     683        appendElement(result, static_cast<Element*>(const_cast<Node*>(node)), convertBlocksToInlines && isBlock(const_cast<Node*>(node)), namespaces, rangeFullySelectsNode);
    658684        break;
    659     }
    660     case Node::CDATA_SECTION_NODE: {
    661         // FIXME: CDATA content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "]]>".
    662         const CDATASection* n = static_cast<const CDATASection*>(node);
    663         append(result, "<![CDATA[");
    664         append(result, n->data());
    665         append(result, "]]>");
     685    case Node::CDATA_SECTION_NODE:
     686        appendCDATASection(result, static_cast<const CDATASection*>(node)->data());
    666687        break;
    667     }
    668688    case Node::ATTRIBUTE_NODE:
    669689    case Node::ENTITY_NODE:
Note: See TracChangeset for help on using the changeset viewer.