15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Igalia S.L.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Motorola Mobility. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/markup.h"
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "CSSPropertyNames.h"
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "CSSValueKeywords.h"
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "HTMLNames.h"
35df95704c49daea886ddad70775bda23618d6274dBen Murdoch#include "bindings/v8/ExceptionState.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSPrimitiveValue.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSValue.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/StylePropertySet.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/CDATASection.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ChildListMutationScope.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ContextFeatures.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/DocumentFragment.h"
43e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/dom/ElementTraversal.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h"
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeTraversal.h"
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Range.h"
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/Editor.h"
4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/MarkupAccumulator.h"
4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/TextIterator.h"
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/VisibleSelection.h"
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/VisibleUnits.h"
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/htmlediting.h"
5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLBodyElement.h"
5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLElement.h"
55e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/html/HTMLHtmlElement.h"
56e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/html/HTMLTableElement.h"
5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLTextFormControlElement.h"
581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/Frame.h"
5953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObject.h"
6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/KURL.h"
61521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/StdLibExtras.h"
62521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/text/StringBuilder.h"
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace std;
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool propertyMissingOrEqualToNone(StylePropertySet*, CSSPropertyID);
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class AttributeChange {
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AttributeChange()
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_name(nullAtom, nullAtom, nullAtom)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AttributeChange(PassRefPtr<Element> element, const QualifiedName& name, const String& value)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_element(element), m_name(name), m_value(value)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void apply()
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
86a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        m_element->setAttribute(m_name, AtomicString(m_value));
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Element> m_element;
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    QualifiedName m_name;
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String m_value;
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static void completeURLs(DocumentFragment& fragment, const String& baseURL)
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<AttributeChange> changes;
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    KURL parsedBaseURL(ParsedURLString, baseURL);
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (Element* element = ElementTraversal::firstWithin(fragment); element; element = ElementTraversal::next(*element, &fragment)) {
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!element->hasAttributes())
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            continue;
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        unsigned length = element->attributeCount();
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (unsigned i = 0; i < length; i++) {
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            const Attribute* attribute = element->attributeItem(i);
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (element->isURLAttribute(*attribute) && !attribute->value().isEmpty())
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                changes.append(AttributeChange(element, attribute->name(), KURL(parsedBaseURL, attribute->value()).string()));
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t numChanges = changes.size();
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < numChanges; ++i)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        changes[i].apply();
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class StyledMarkupAccumulator : public MarkupAccumulator {
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode };
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StyledMarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs, EAnnotateForInterchange, const Range*, Node* highestNodeToBeSerialized = 0);
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* serializeNodes(Node* startNode, Node* pastEnd);
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void appendString(const String& s) { return MarkupAccumulator::appendString(s); }
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void wrapWithNode(Node*, bool convertBlocksToInlines = false, RangeFullySelectsNode = DoesFullySelectNode);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void wrapWithStyleNode(StylePropertySet*, Document*, bool isBlock = false);
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String takeResults();
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, Document*, bool isBlock = false);
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const String& styleNodeCloseTag(bool isBlock = false);
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void appendText(StringBuilder& out, Text*);
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String renderedText(const Node*, const Range*);
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String stringValueForRange(const Node*, const Range*);
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void appendElement(StringBuilder& out, Element*, bool addDisplayInline, RangeFullySelectsNode);
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void appendElement(StringBuilder& out, Element* element, Namespaces*) { appendElement(out, element, false, DoesFullySelectNode); }
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum NodeTraversalMode { EmitString, DoNotEmitString };
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTraversalMode);
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; }
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool shouldApplyWrappingStyle(Node* node) const
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode() == node->parentNode()
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            && m_wrappingStyle && m_wrappingStyle->style();
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<String> m_reversedPrecedingMarkup;
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const EAnnotateForInterchange m_shouldAnnotate;
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* m_highestNodeToBeSerialized;
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<EditingStyle> m_wrappingStyle;
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline StyledMarkupAccumulator::StyledMarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate,
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Range* range, Node* highestNodeToBeSerialized)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : MarkupAccumulator(nodes, shouldResolveURLs, range)
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_shouldAnnotate(shouldAnnotate)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_highestNodeToBeSerialized(highestNodeToBeSerialized)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void StyledMarkupAccumulator::wrapWithNode(Node* node, bool convertBlocksToInlines, RangeFullySelectsNode rangeFullySelectsNode)
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder markup;
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node->isElementNode())
165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        appendElement(markup, toElement(node), convertBlocksToInlines && isBlock(const_cast<Node*>(node)), rangeFullySelectsNode);
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendStartMarkup(markup, node, 0);
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_reversedPrecedingMarkup.append(markup.toString());
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    appendEndTag(node);
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_nodes)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_nodes->append(node);
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style, Document* document, bool isBlock)
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder openTag;
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    appendStyleNodeOpenTag(openTag, style, document, isBlock);
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_reversedPrecedingMarkup.append(openTag.toString());
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    appendString(styleNodeCloseTag(isBlock));
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void StyledMarkupAccumulator::appendStyleNodeOpenTag(StringBuilder& out, StylePropertySet* style, Document* document, bool isBlock)
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // wrappingStyleForSerialization should have removed -webkit-text-decorations-in-effect
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(propertyMissingOrEqualToNone(style, CSSPropertyWebkitTextDecorationsInEffect));
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isBlock)
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        out.appendLiteral("<div style=\"");
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        out.appendLiteral("<span style=\"");
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    appendAttributeValue(out, style->asText(), document->isHTMLDocument());
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    out.append('\"');
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    out.append('>');
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const String& StyledMarkupAccumulator::styleNodeCloseTag(bool isBlock)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1973c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    DEFINE_STATIC_LOCAL(const String, divClose, ("</div>"));
1983c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    DEFINE_STATIC_LOCAL(const String, styleSpanClose, ("</span>"));
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return isBlock ? divClose : styleSpanClose;
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String StyledMarkupAccumulator::takeResults()
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder result;
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result.reserveCapacity(totalLength(m_reversedPrecedingMarkup) + length());
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = m_reversedPrecedingMarkup.size(); i > 0; --i)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.append(m_reversedPrecedingMarkup[i - 1]);
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    concatenateMarkup(result);
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We remove '\0' characters because they are not visibly rendered to the user.
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.toString().replace(0, "");
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void StyledMarkupAccumulator::appendText(StringBuilder& out, Text* text)
21702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const bool parentIsTextarea = text->parentElement() && text->parentElement()->tagQName() == textareaTag;
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextarea;
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (wrappingSpan) {
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy();
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Make sure spans are inline style in paste side e.g. span { display: block }.
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        wrappingStyle->forceInline();
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: Should this be included in forceInline?
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone);
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2288abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        appendStyleNodeOpenTag(out, wrappingStyle->style(), &text->document());
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!shouldAnnotate() || parentIsTextarea)
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        MarkupAccumulator::appendText(out, text);
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const bool useRenderedText = !enclosingNodeWithTag(firstPositionInNode(text), selectTag);
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String content = useRenderedText ? renderedText(text, m_range) : stringValueForRange(text, m_range);
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        StringBuilder buffer;
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendCharactersReplacingEntities(buffer, content, 0, content.length(), EntityMaskInPCDATA);
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        out.append(convertHTMLTextToInterchangeFormat(buffer.toString(), text));
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (wrappingSpan)
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        out.append(styleNodeCloseTag());
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
24402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String StyledMarkupAccumulator::renderedText(const Node* node, const Range* range)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node->isTextNode())
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String();
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2508abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    const Text* textNode = toText(node);
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned startOffset = 0;
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned endOffset = textNode->length();
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (range && node == range->startContainer())
255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        startOffset = range->startOffset();
256926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (range && node == range->endContainer())
257926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        endOffset = range->endOffset();
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Position start = createLegacyEditingPosition(const_cast<Node*>(node), startOffset);
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Position end = createLegacyEditingPosition(const_cast<Node*>(node), endOffset);
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return plainText(Range::create(node->document(), start, end).get());
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String StyledMarkupAccumulator::stringValueForRange(const Node* node, const Range* range)
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!range)
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return node->nodeValue();
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String str = node->nodeValue();
270926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (node == range->endContainer())
271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        str.truncate(range->endOffset());
272926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (node == range->startContainer())
273926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        str.remove(0, range->startOffset());
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return str;
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element* element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    const bool documentIsHTML = element->document().isHTMLDocument();
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    appendOpenTag(out, element, 0);
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const unsigned length = element->hasAttributes() ? element->attributeCount() : 0;
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const bool shouldAnnotateOrForceInline = element->isHTMLElement() && (shouldAnnotate() || addDisplayInline);
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldApplyWrappingStyle(element);
285926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (unsigned i = 0; i < length; ++i) {
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const Attribute* attribute = element->attributeItem(i);
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We'll handle the style attribute separately, below.
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (attribute->name() == styleAttr && shouldOverrideStyleAttr)
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendAttribute(out, element, *attribute, 0);
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldOverrideStyleAttr) {
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<EditingStyle> newInlineStyle;
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (shouldApplyWrappingStyle(element)) {
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newInlineStyle = m_wrappingStyle->copy();
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newInlineStyle->removePropertiesInElementDefaultStyle(element);
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newInlineStyle->removeStyleConflictingWithStyleOfNode(element);
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newInlineStyle = EditingStyle::create();
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
303591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        if (element->isStyledElement() && element->inlineStyle())
304591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            newInlineStyle->overrideWithStyle(element->inlineStyle());
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (shouldAnnotateOrForceInline) {
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (shouldAnnotate())
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                newInlineStyle->mergeStyleFromRulesForSerialization(toHTMLElement(element));
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (addDisplayInline)
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                newInlineStyle->forceInline();
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // 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
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // only the ones that affect it and the nodes within it.
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (rangeFullySelectsNode == DoesNotFullySelectNode && newInlineStyle->style())
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                newInlineStyle->style()->removeProperty(CSSPropertyFloat);
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!newInlineStyle->isEmpty()) {
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            out.appendLiteral(" style=\"");
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            appendAttributeValue(out, newInlineStyle->style()->asText(), documentIsHTML);
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            out.append('\"');
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    appendCloseTag(out, element);
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* StyledMarkupAccumulator::serializeNodes(Node* startNode, Node* pastEnd)
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_highestNodeToBeSerialized) {
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node* lastClosed = traverseNodesForSerialization(startNode, pastEnd, DoNotEmitString);
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_highestNodeToBeSerialized = lastClosed;
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode())
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(m_highestNodeToBeSerialized->parentNode(), shouldAnnotate());
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return traverseNodesForSerialization(startNode, pastEnd, EmitString);
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTraversalMode traversalMode)
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const bool shouldEmit = traversalMode == EmitString;
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<Node*> ancestorsToClose;
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* next;
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* lastClosed = 0;
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (Node* n = startNode; n != pastEnd; n = next) {
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // According to <rdar://problem/5730668>, it is possible for n to blow
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // past pastEnd and become null here. This shouldn't be possible.
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This null check will prevent crashes (but create too much markup)
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // and the ASSERT will hopefully lead us to understanding the problem.
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(n);
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!n)
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
35602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
35751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        next = NodeTraversal::next(*n);
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool openedTag = false;
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isBlock(n) && canHaveChildrenForEditing(n) && next == pastEnd)
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Don't write out empty block containers that aren't fully selected.
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!n->renderer() && !enclosingNodeWithTag(firstPositionInOrBeforeNode(n), selectTag)) {
36551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            next = NodeTraversal::nextSkippingChildren(*n);
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Don't skip over pastEnd.
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (pastEnd && pastEnd->isDescendantOf(n))
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                next = pastEnd;
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Add the node to the markup if we're not skipping the descendants
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (shouldEmit)
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                appendStartTag(n);
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If node has no children, close the tag now.
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!n->childNodeCount()) {
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (shouldEmit)
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    appendEndTag(n);
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                lastClosed = n;
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else {
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                openedTag = true;
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ancestorsToClose.append(n);
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we didn't insert open tag and there's no more siblings or we're at the end of the traversal, take care of ancestors.
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: What happens if we just inserted open tag and reached the end?
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!openedTag && (!n->nextSibling() || next == pastEnd)) {
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Close up the ancestors.
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (!ancestorsToClose.isEmpty()) {
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                Node* ancestor = ancestorsToClose.last();
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (next != pastEnd && next->isDescendantOf(ancestor))
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    break;
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Not at the end of the range, close ancestors up to sibling of next node.
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (shouldEmit)
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    appendEndTag(ancestor);
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                lastClosed = ancestor;
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ancestorsToClose.removeLast();
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Surround the currently accumulated markup with markup for ancestors we never opened as we leave the subtree(s) rooted at those ancestors.
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ContainerNode* nextParent = next ? next->parentNode() : 0;
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (next != pastEnd && n != nextParent) {
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                Node* lastAncestorClosedOrSelf = n->isDescendantOf(lastClosed) ? lastClosed : n;
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (ContainerNode* parent = lastAncestorClosedOrSelf->parentNode(); parent && parent != nextParent; parent = parent->parentNode()) {
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // All ancestors that aren't in the ancestorsToClose list should either be a) unrendered:
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (!parent->renderer())
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        continue;
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // or b) ancestors that we never encountered during a pre-order traversal starting at startNode:
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    ASSERT(startNode->isDescendantOf(parent));
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (shouldEmit)
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        wrapWithNode(parent);
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    lastClosed = parent;
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return lastClosed;
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool isHTMLBlockElement(const Node* node)
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node->hasTagName(tdTag)
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || node->hasTagName(thTag)
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || isNonTableCellHTMLBlockElement(node);
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Node* ancestorToRetainStructureAndAppearanceForBlock(Node* commonAncestorBlock)
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!commonAncestorBlock)
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (commonAncestorBlock->hasTagName(tbodyTag) || commonAncestorBlock->hasTagName(trTag)) {
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ContainerNode* table = commonAncestorBlock->parentNode();
435e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        while (table && !isHTMLTableElement(table))
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            table = table->parentNode();
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return table;
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isNonTableCellHTMLBlockElement(commonAncestorBlock))
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return commonAncestorBlock;
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline Node* ancestorToRetainStructureAndAppearance(Node* commonAncestor)
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return ancestorToRetainStructureAndAppearanceForBlock(enclosingBlock(commonAncestor));
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline Node* ancestorToRetainStructureAndAppearanceWithNoRenderer(Node* commonAncestor)
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* commonAncestorBlock = enclosingNodeOfType(firstPositionInOrBeforeNode(commonAncestor), isHTMLBlockElement);
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return ancestorToRetainStructureAndAppearanceForBlock(commonAncestorBlock);
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool propertyMissingOrEqualToNone(StylePropertySet* style, CSSPropertyID propertyID)
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style)
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!value)
4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!value->isPrimitiveValue())
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
4673c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    return toCSSPrimitiveValue(value.get())->getValueID() == CSSValueNone;
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool needInterchangeNewlineAfter(const VisiblePosition& v)
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    VisiblePosition next = v.next();
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode();
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode();
4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Add an interchange newline if a paragraph break is selected and a br won't already be added to the markup to represent it.
4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return isEndOfParagraph(v) && isStartOfParagraph(next) && !(upstreamNode->hasTagName(brTag) && upstreamNode == downstreamNode);
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static PassRefPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* node)
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node->isHTMLElement())
4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Having to const_cast here is ugly, but it is quite a bit of work to untangle
4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the non-const-ness of styleFromMatchedRulesForElement.
4868abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    HTMLElement* element = const_cast<HTMLElement*>(toHTMLElement(node));
4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<EditingStyle> style = EditingStyle::create(element->inlineStyle());
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    style->mergeStyleFromRules(element);
4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return style.release();
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool isElementPresentational(const Node* node)
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName(strikeTag)
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName(bTag) || node->hasTagName(strongTag);
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
49853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static Node* highestAncestorToWrapMarkup(const Range* range, EAnnotateForInterchange shouldAnnotate, Node* constrainingAncestor)
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5001fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    Node* commonAncestor = range->commonAncestorContainer(IGNORE_EXCEPTION);
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(commonAncestor);
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* specialCommonAncestor = 0;
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldAnnotate == AnnotateForInterchange) {
50402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        // Include ancestors that aren't completely inside the range but are required to retain
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // the structure and appearance of the copied markup.
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        specialCommonAncestor = ancestorToRetainStructureAndAppearance(commonAncestor);
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
508926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (Node* parentListNode = enclosingNodeOfType(firstPositionInOrBeforeNode(range->firstNode()), isListItem)) {
509926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (WebCore::areRangesEqual(VisibleSelection::selectionFromContentsOfNode(parentListNode).toNormalizedRange().get(), range)) {
510926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                specialCommonAncestor = parentListNode->parentNode();
511926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                while (specialCommonAncestor && !isListElement(specialCommonAncestor))
512926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    specialCommonAncestor = specialCommonAncestor->parentNode();
513926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
514926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
515926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Retain the Mail quote level by including all ancestor mail block quotes.
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (Node* highestMailBlockquote = highestEnclosingNodeOfType(firstPositionInOrBeforeNode(range->firstNode()), isMailBlockquote, CanCrossEditingBoundary))
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            specialCommonAncestor = highestMailBlockquote;
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* checkAncestor = specialCommonAncestor ? specialCommonAncestor : commonAncestor;
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (checkAncestor->renderer()) {
52353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        Node* newSpecialCommonAncestor = highestEnclosingNodeOfType(firstPositionInNode(checkAncestor), &isElementPresentational, CanCrossEditingBoundary, constrainingAncestor);
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (newSpecialCommonAncestor)
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            specialCommonAncestor = newSpecialCommonAncestor;
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If a single tab is selected, commonAncestor will be a text node inside a tab span.
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If two or more tabs are selected, commonAncestor will be the tab span.
53002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // In either case, if there is a specialCommonAncestor already, it will necessarily be above
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // any tab span that needs to be included.
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!specialCommonAncestor && isTabSpanTextNode(commonAncestor))
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        specialCommonAncestor = commonAncestor->parentNode();
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!specialCommonAncestor && isTabSpanNode(commonAncestor))
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        specialCommonAncestor = commonAncestor;
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (Node *enclosingAnchor = enclosingNodeWithTag(firstPositionInNode(specialCommonAncestor ? specialCommonAncestor : commonAncestor), aTag))
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        specialCommonAncestor = enclosingAnchor;
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return specialCommonAncestor;
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
54302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch// FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForInterchange?
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: At least, annotation and style info should probably not be included in range.markupString()
5458abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)static String createMarkupInternal(Document& document, const Range* range, const Range* updatedRange, Vector<Node*>* nodes,
54653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs, Node* constrainingAncestor)
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
548926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(range);
549926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(updatedRange);
5503c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, ("<br class=\"" AppleInterchangeNewline "\">"));
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5521fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    bool collapsed = updatedRange->collapsed(ASSERT_NO_EXCEPTION);
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (collapsed)
554926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return emptyString();
5551fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    Node* commonAncestor = updatedRange->commonAncestorContainer(ASSERT_NO_EXCEPTION);
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!commonAncestor)
557926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return emptyString();
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5598abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    document.updateLayoutIgnorePendingStylesheets();
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* body = enclosingNodeWithTag(firstPositionInNode(commonAncestor), bodyTag);
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* fullySelectedRoot = 0;
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Do this for all fully selected blocks, not just the body.
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (body && areRangesEqual(VisibleSelection::selectionFromContentsOfNode(body).toNormalizedRange().get(), range))
5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fullySelectedRoot = body;
56653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Node* specialCommonAncestor = highestAncestorToWrapMarkup(updatedRange, shouldAnnotate, constrainingAncestor);
567926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    StyledMarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate, updatedRange, specialCommonAncestor);
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* pastEnd = updatedRange->pastLastNode();
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* startNode = updatedRange->firstNode();
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    VisiblePosition visibleStart(updatedRange->startPosition(), VP_DEFAULT_AFFINITY);
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    VisiblePosition visibleEnd(updatedRange->endPosition(), VP_DEFAULT_AFFINITY);
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter(visibleStart)) {
574926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (visibleStart == visibleEnd.previous())
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return interchangeNewlineString;
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        accumulator.appendString(interchangeNewlineString);
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        startNode = visibleStart.next().deepEquivalent().deprecatedNode();
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5801fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0, ASSERT_NO_EXCEPTION) >= 0)
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return interchangeNewlineString;
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* lastClosed = accumulator.serializeNodes(startNode, pastEnd);
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (specialCommonAncestor && lastClosed) {
5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Also include all of the ancestors of lastClosed up to this special ancestor.
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (ContainerNode* ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (ancestor == fullySelectedRoot && !convertBlocksToInlines) {
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                RefPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Bring the background attribute over, but not as an attribute because a background attribute on a div
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // appears to have no effect.
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundImage))
595926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    && toElement(fullySelectedRoot)->hasAttribute(backgroundAttr))
596926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    fullySelectedRootStyle->style()->setProperty(CSSPropertyBackgroundImage, "url('" + toElement(fullySelectedRoot)->getAttribute(backgroundAttr) + "')");
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (fullySelectedRootStyle->style()) {
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // Reset the CSS properties to avoid an assertion error in addStyleMarkup().
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // This assertion is caused at least when we select all text of a <body> element whose
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // 'text-decoration' property is "inherit", and copy it.
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyTextDecoration))
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        fullySelectedRootStyle->style()->setProperty(CSSPropertyTextDecoration, CSSValueNone);
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyWebkitTextDecorationsInEffect))
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        fullySelectedRootStyle->style()->setProperty(CSSPropertyWebkitTextDecorationsInEffect, CSSValueNone);
6068abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                    accumulator.wrapWithStyleNode(fullySelectedRootStyle->style(), &document, true);
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else {
6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Since this node and all the other ancestors are not in the selection we want to set RangeFullySelectsNode to DoesNotFullySelectNode
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // so that styles that affect the exterior of the node are not included.
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                accumulator.wrapWithNode(ancestor, convertBlocksToInlines, StyledMarkupAccumulator::DoesNotFullySelectNode);
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (nodes)
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                nodes->append(ancestor);
61502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            lastClosed = ancestor;
61702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (ancestor == specialCommonAncestor)
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: The interchange newline should be placed in the block that it's in, not after all of the content, unconditionally.
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter(visibleEnd.previous()))
6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        accumulator.appendString(interchangeNewlineString);
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return accumulator.takeResults();
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
63053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs, Node* constrainingAncestor)
631926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
632926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!range)
633926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return emptyString();
634926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
6358abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Document& document = range->ownerDocument();
636926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const Range* updatedRange = range;
637926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
63853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return createMarkupInternal(document, range, updatedRange, nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor);
639926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
640926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
6418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document& document, const String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy)
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We use a fake body element here to trick the HTML parser to using the InBody insertion mode.
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document);
6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
646926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
647926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    fragment->parseHTML(markup, fakeBody.get(), parserContentPolicy);
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6498abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (!baseURL.isEmpty() && baseURL != blankURL() && baseURL != document.baseURL())
65051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        completeURLs(*fragment, baseURL);
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return fragment.release();
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const char fragmentMarkerTag[] = "webkit-fragment-marker";
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool findNodesSurroundingContext(Document* document, RefPtr<Node>& nodeBeforeContext, RefPtr<Node>& nodeAfterContext)
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
65951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (Node* node = document->firstChild(); node; node = NodeTraversal::next(*node)) {
6608abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (node->nodeType() == Node::COMMENT_NODE && toCharacterData(node)->data() == fragmentMarkerTag) {
6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!nodeBeforeContext)
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                nodeBeforeContext = node;
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else {
6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                nodeAfterContext = node;
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return true;
6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void trimFragment(DocumentFragment* fragment, Node* nodeBeforeContext, Node* nodeAfterContext)
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Node> next;
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RefPtr<Node> node = fragment->firstChild(); node; node = next) {
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (nodeBeforeContext->isDescendantOf(node.get())) {
67751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            next = NodeTraversal::next(*node);
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
68051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        next = NodeTraversal::nextSkippingChildren(*node);
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!node->contains(nodeAfterContext));
6821fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION);
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (nodeBeforeContext == node)
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(nodeAfterContext->parentNode());
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RefPtr<Node> node = nodeAfterContext; node; node = next) {
68951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        next = NodeTraversal::nextSkippingChildren(*node);
6901fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION);
6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document& document, const String& markup, unsigned fragmentStart, unsigned fragmentEnd,
695926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const String& baseURL, ParserContentPolicy parserContentPolicy)
6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Need to handle the case where the markup already contains these markers.
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder taggedMarkup;
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    taggedMarkup.append(markup.left(fragmentStart));
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag);
7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    taggedMarkup.append(markup.substring(fragmentStart, fragmentEnd - fragmentStart));
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag);
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    taggedMarkup.append(markup.substring(fragmentEnd));
7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
706926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<DocumentFragment> taggedFragment = createFragmentFromMarkup(document, taggedMarkup.toString(), baseURL, parserContentPolicy);
707e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    RefPtr<Document> taggedDocument = Document::create();
7088abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    taggedDocument->setContextFeatures(document.contextFeatures());
7091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
7101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // FIXME: It's not clear what this code is trying to do. It puts nodes as direct children of a
7111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Document that are not normally allowed by using the parser machinery.
71219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    taggedDocument->parserTakeAllChildrenFrom(*taggedFragment);
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Node> nodeBeforeContext;
7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Node> nodeAfterContext;
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, nodeAfterContext))
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7198abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    RefPtr<Range> range = Range::create(*taggedDocument.get(),
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(),
7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        positionBeforeNode(nodeAfterContext.get()).parentAnchoredEquivalent());
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7231fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    Node* commonAncestor = range->commonAncestorContainer(ASSERT_NO_EXCEPTION);
7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRenderer(commonAncestor);
7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // When there's a special common ancestor outside of the fragment, we must include it as well to
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // preserve the structure and appearance of the fragment. For example, if the fragment contains
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // TD, we need to include the enclosing TABLE tag as well.
7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
730926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (specialCommonAncestor)
731e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        fragment->appendChild(specialCommonAncestor);
732926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    else
73319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        fragment->parserTakeAllChildrenFrom(toContainerNode(*commonAncestor));
7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    trimFragment(fragment.get(), nodeBeforeContext.get(), nodeAfterContext.get());
7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return fragment;
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, Vector<QualifiedName>* tagNamesToSkip)
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return "";
7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MarkupAccumulator accumulator(nodes, shouldResolveURLs);
74653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return accumulator.serializeNodes(const_cast<Node*>(node), childrenOnly, tagNamesToSkip);
7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void fillContainerFromString(ContainerNode* paragraph, const String& string)
7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7518abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Document& document = paragraph->document();
7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (string.isEmpty()) {
754e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        paragraph->appendChild(createBlockPlaceholderElement(document));
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
75806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(string.find('\n') == kNotFound);
7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<String> tabList;
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    string.split('\t', true, tabList);
7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String tabText = emptyString();
7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool first = true;
7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t numEntries = tabList.size();
7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < numEntries; ++i) {
7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const String& s = tabList[i];
7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // append the non-tab textual part
7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!s.isEmpty()) {
7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!tabText.isEmpty()) {
771e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                paragraph->appendChild(createTabSpanElement(document, tabText));
7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                tabText = emptyString();
7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
7748abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            RefPtr<Node> textNode = document.createTextNode(stringWithRebalancedWhitespace(s, first, i + 1 == numEntries));
775e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            paragraph->appendChild(textNode.release());
7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // there is a tab after every entry, except the last entry
7795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // (if the last character is a tab, the list gets an extra empty entry)
7805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (i + 1 != numEntries)
7815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            tabText.append('\t');
782926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        else if (!tabText.isEmpty())
783e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            paragraph->appendChild(createTabSpanElement(document, tabText));
784926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        first = false;
7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool isPlainTextMarkup(Node *node)
7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
791926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!node->isElementNode() || !node->hasTagName(divTag) || toElement(node)->hasAttributes())
7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
79302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node->childNodeCount() == 1 && (node->firstChild()->isTextNode() || (node->firstChild()->firstChild())))
7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
79602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return (node->childNodeCount() == 2 && isTabSpanTextNode(node->firstChild()->firstChild()) && node->firstChild()->nextSibling()->isTextNode());
7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
80023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdochstatic bool shouldPreserveNewline(const Range& range)
80123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch{
80223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    if (Node* node = range.firstNode()) {
80323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch        if (RenderObject* renderer = node->renderer())
80423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch            return renderer->style()->preserveNewline();
80523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    }
80623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
80723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    if (Node* node = range.startPosition().anchorNode()) {
80823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch        if (RenderObject* renderer = node->renderer())
80923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch            return renderer->style()->preserveNewline();
81023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    }
81123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
81223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    return false;
81323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch}
81423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
8155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String& text)
8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!context)
8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8208abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Document& document = context->ownerDocument();
8218abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    RefPtr<DocumentFragment> fragment = document.createDocumentFragment();
82202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
8235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (text.isEmpty())
8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return fragment.release();
8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String string = text;
8275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    string.replace("\r\n", "\n");
8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    string.replace('\r', '\n');
8295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
83023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    if (shouldPreserveNewline(*context)) {
8318abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        fragment->appendChild(document.createTextNode(string));
8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (string.endsWith('\n')) {
8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RefPtr<Element> element = createBreakElement(document);
83402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch            element->setAttribute(classAttr, AppleInterchangeNewline);
835e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            fragment->appendChild(element.release());
8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return fragment.release();
8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // A string with no newlines gets added inline, rather than being put into a paragraph.
84106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (string.find('\n') == kNotFound) {
8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fillContainerFromString(fragment.get(), string);
8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return fragment.release();
8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Break string into paragraphs. Extra line breaks turn into empty paragraphs.
8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* blockNode = enclosingBlock(context->firstNode());
848926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Element* block = toElement(blockNode);
8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool useClonesOfEnclosingBlock = blockNode
8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && blockNode->isElementNode()
8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && !block->hasTagName(bodyTag)
852e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        && !isHTMLHtmlElement(block)
8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && block != editableRootForPosition(context->startPosition());
8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool useLineBreak = enclosingTextFormControl(context->startPosition());
8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<String> list;
8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    string.split('\n', true, list); // true gets us empty strings in the list
8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t numLines = list.size();
8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < numLines; ++i) {
8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const String& s = list[i];
8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<Element> element;
8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (s.isEmpty() && i + 1 == numLines) {
8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // For last line, use the "magic BR" rather than a P.
8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            element = createBreakElement(document);
8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            element->setAttribute(classAttr, AppleInterchangeNewline);
8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (useLineBreak) {
8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            element = createBreakElement(document);
8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fillContainerFromString(fragment.get(), s);
8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (useClonesOfEnclosingBlock)
8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                element = block->cloneElementWithoutChildren();
8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                element = createDefaultParagraphElement(document);
8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fillContainerFromString(element.get(), s);
8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
877e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        fragment->appendChild(element.release());
8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return fragment.release();
8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<DocumentFragment> createFragmentFromNodes(Document *document, const Vector<Node*>& nodes)
8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!document)
8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<DocumentFragment> fragment = document->createDocumentFragment();
8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t size = nodes.size();
8905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < size; ++i) {
8918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        RefPtr<Element> element = createDefaultParagraphElement(*document);
892e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        element->appendChild(nodes[i]);
893e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        fragment->appendChild(element.release());
8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return fragment.release();
8975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String createFullMarkup(const Node* node)
9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String();
90302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9048abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Frame* frame = node->document().frame();
9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!frame)
9065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String();
9075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
90802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // FIXME: This is never "for interchange". Is that right?
9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String markupString = createMarkup(node, IncludeNode, 0);
9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node::NodeType nodeType = node->nodeType();
9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (nodeType != Node::DOCUMENT_NODE && nodeType != Node::DOCUMENT_TYPE_NODE)
9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        markupString = frame->documentTypeString() + markupString;
9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return markupString;
9155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String createFullMarkup(const Range* range)
9185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!range)
9205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String();
9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = range->startContainer();
9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String();
92502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9268abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Frame* frame = node->document().frame();
9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!frame)
9285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String();
9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: This is always "for interchange". Is that right? See the previous method.
93102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    return frame->documentTypeString() + createMarkup(range, 0, AnnotateForInterchange);
9325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String urlToMarkup(const KURL& url, const String& title)
9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder markup;
9375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    markup.append("<a href=\"");
9385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    markup.append(url.string());
9395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    markup.append("\">");
9405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MarkupAccumulator::appendCharactersReplacingEntities(markup, title, 0, title.length(), EntityMaskInPCDATA);
9415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    markup.append("</a>");
9425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return markup.toString();
9435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
94551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& markup, Element* contextElement, ParserContentPolicy parserContentPolicy, const char* method, ExceptionState& exceptionState)
9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9478abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Document& document = contextElement->hasTagName(templateTag) ? contextElement->document().ensureTemplateDocument() : contextElement->document();
9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9508abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (document.isHTMLDocument()) {
951926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        fragment->parseHTML(markup, contextElement, parserContentPolicy);
9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return fragment;
9535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
955926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool wasValid = fragment->parseXML(markup, contextElement, parserContentPolicy);
9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!wasValid) {
957a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        exceptionState.throwDOMException(SyntaxError, "The provided markup is invalid XML, and therefore cannot be inserted into an XML document.");
9585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
9595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return fragment.release();
9615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9638abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)PassRefPtr<DocumentFragment> createFragmentForTransformToFragment(const String& sourceString, const String& sourceMIMEType, Document& outputDoc)
9645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9658abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    RefPtr<DocumentFragment> fragment = outputDoc.createDocumentFragment();
96602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (sourceMIMEType == "text/html") {
9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // As far as I can tell, there isn't a spec for how transformToFragment is supposed to work.
9695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Based on the documentation I can find, it looks like we want to start parsing the fragment in the InBody insertion mode.
9705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Unfortunately, that's an implementation detail of the parser.
9715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We achieve that effect here by passing in a fake body element as context for the fragment.
9725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(outputDoc);
9735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fragment->parseHTML(sourceString, fakeBody.get());
9748abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    } else if (sourceMIMEType == "text/plain") {
9755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fragment->parserAppendChild(Text::create(outputDoc, sourceString));
9768abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    } else {
9775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool successfulParse = fragment->parseXML(sourceString, 0);
9785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!successfulParse)
9795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 0;
9805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
98102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Do we need to mess with URLs here?
98302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return fragment.release();
9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void removeElementPreservingChildren(PassRefPtr<DocumentFragment> fragment, HTMLElement* element)
9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Node> nextChild;
9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RefPtr<Node> child = element->firstChild(); child; child = nextChild) {
9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nextChild = child->nextSibling();
992e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        element->removeChild(child.get());
993e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        fragment->insertBefore(child, element);
9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
995e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    fragment->removeChild(element);
9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
99851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, HTMLElement* element, ParserContentPolicy parserContentPolicy, ExceptionState& exceptionState)
9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element);
1001f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    if (element->ieForbidsInsertHTML() || element->hasLocalName(colTag) || element->hasLocalName(colgroupTag) || element->hasLocalName(framesetTag)
10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || element->hasLocalName(headTag) || element->hasLocalName(styleTag) || element->hasLocalName(titleTag)) {
1003a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        exceptionState.throwDOMException(NotSupportedError, "The range's container is '" + element->localName() + "', which is not supported.");
10045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
100751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, element, parserContentPolicy, "createContextualFragment", exceptionState);
10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!fragment)
10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We need to pop <html> and <body> elements and remove <head> to
10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // accommodate folks passing complete HTML documents to make the
10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // child of an element.
10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Node> nextNode;
10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) {
10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nextNode = node->nextSibling();
1018e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        if (isHTMLHtmlElement(node.get()) || node->hasTagName(headTag) || node->hasTagName(bodyTag)) {
1019f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            HTMLElement* element = toHTMLElement(node);
10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (Node* firstChild = element->firstChild())
10215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                nextNode = firstChild;
10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            removeElementPreservingChildren(fragment, element);
10235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return fragment.release();
10265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
102851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void replaceChildrenWithFragment(ContainerNode* container, PassRefPtr<DocumentFragment> fragment, ExceptionState& exceptionState)
10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1030f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    ASSERT(container);
10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<ContainerNode> containerNode(container);
10325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1033f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    ChildListMutationScope mutation(*containerNode);
10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!fragment->firstChild()) {
10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        containerNode->removeChildren();
10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1040e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (containerNode->hasOneTextChild() && fragment->hasOneTextChild()) {
1041521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        toText(containerNode->firstChild())->setData(toText(fragment->firstChild())->data());
10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1045e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (containerNode->hasOneChild()) {
104651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        containerNode->replaceChild(fragment, containerNode->firstChild(), exceptionState);
10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    containerNode->removeChildren();
105151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    containerNode->appendChild(fragment, exceptionState);
10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
105451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void replaceChildrenWithText(ContainerNode* container, const String& text, ExceptionState& exceptionState)
10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1056f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    ASSERT(container);
10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<ContainerNode> containerNode(container);
10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1059f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    ChildListMutationScope mutation(*containerNode);
10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1061e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (containerNode->hasOneTextChild()) {
1062521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        toText(containerNode->firstChild())->setData(text);
10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Text> textNode = Text::create(containerNode->document(), text);
10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1068e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (containerNode->hasOneChild()) {
106951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        containerNode->replaceChild(textNode.release(), containerNode->firstChild(), exceptionState);
10705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    containerNode->removeChildren();
107451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    containerNode->appendChild(textNode.release(), exceptionState);
10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
107751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void mergeWithNextTextNode(PassRefPtr<Node> node, ExceptionState& exceptionState)
107819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles){
107919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    ASSERT(node && node->isTextNode());
108019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    Node* next = node->nextSibling();
108119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (!next || !next->isTextNode())
108219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return;
108319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
108419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    RefPtr<Text> textNode = toText(node.get());
108519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    RefPtr<Text> textNext = toText(next);
108619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    textNode->appendData(textNext->data());
108719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (textNext->parentNode()) // Might have been removed by mutation event.
108851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        textNext->remove(exceptionState);
108919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)}
109019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1092