15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Text.h"
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "SVGNames.h"
26df95704c49daea886ddad70775bda23618d6274dBen Murdoch#include "bindings/v8/ExceptionState.h"
27df95704c49daea886ddad70775bda23618d6274dBen Murdoch#include "bindings/v8/ExceptionStatePlaceholder.h"
2893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "core/css/resolver/StyleResolver.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h"
30e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/dom/NodeRenderStyle.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeRenderingContext.h"
3293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "core/dom/ScopedEventQueue.h"
33e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/ShadowRoot.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderCombineText.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderText.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGInlineText.h"
3793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/text/CString.h"
3893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/text/StringBuilder.h"
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace std;
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<Text> Text::create(Document* document, const String& data)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return adoptRef(new Text(document, data, CreateText));
47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
48926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)PassRefPtr<Text> Text::createEditingText(Document* document, const String& data)
50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return adoptRef(new Text(document, data, CreateEditingText));
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
54df95704c49daea886ddad70775bda23618d6274dBen MurdochPassRefPtr<Text> Text::splitText(unsigned offset, ExceptionState& es)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
56e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // IndexSizeError: Raised if the specified offset is negative or greater than
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the number of 16-bit units in data.
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (offset > length()) {
59df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(IndexSizeError);
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    EventQueueScope scope;
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String oldStr = data();
6553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<Text> newText = cloneWithData(oldStr.substring(offset));
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setDataWithoutUpdate(oldStr.substring(0, offset));
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    didModifyData(oldStr);
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (parentNode())
71df95704c49daea886ddad70775bda23618d6274dBen Murdoch        parentNode()->insertBefore(newText.get(), nextSibling(), es);
72df95704c49daea886ddad70775bda23618d6274dBen Murdoch    if (es.hadException())
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (parentNode())
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        document()->textNodeSplit(this);
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (renderer())
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        toRenderText(renderer())->setTextWithOffset(dataImpl(), 0, oldStr.length());
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return newText.release();
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const Text* earliestLogicallyAdjacentTextNode(const Text* t)
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Node* n = t;
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while ((n = n->previousSibling())) {
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node::NodeType type = n->nodeType();
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) {
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            t = static_cast<const Text*>(n);
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return t;
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const Text* latestLogicallyAdjacentTextNode(const Text* t)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Node* n = t;
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while ((n = n->nextSibling())) {
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node::NodeType type = n->nodeType();
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) {
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            t = static_cast<const Text*>(n);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return t;
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String Text::wholeText() const
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Text* startText = earliestLogicallyAdjacentTextNode(this);
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Text* endText = latestLogicallyAdjacentTextNode(this);
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* onePastEndText = endText->nextSibling();
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned resultLength = 0;
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) {
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!n->isTextNode())
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const Text* t = static_cast<const Text*>(n);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const String& data = t->data();
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (std::numeric_limits<unsigned>::max() - data.length() < resultLength)
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CRASH();
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        resultLength += data.length();
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder result;
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result.reserveCapacity(resultLength);
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) {
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!n->isTextNode())
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const Text* t = static_cast<const Text*>(n);
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.append(t->data());
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(result.length() == resultLength);
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.toString();
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
143e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)PassRefPtr<Text> Text::replaceWholeText(const String& newText)
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Remove all adjacent text nodes, and replace the contents of this one.
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Protect startText and endText against mutation event handlers removing the last ref
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Text> startText = const_cast<Text*>(earliestLogicallyAdjacentTextNode(this));
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Text> endText = const_cast<Text*>(latestLogicallyAdjacentTextNode(this));
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Text> protectedThis(this); // Mutation event handlers could cause our last ref to go away
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<ContainerNode> parent = parentNode(); // Protect against mutation handlers moving this node during traversal
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RefPtr<Node> n = startText; n && n != this && n->isTextNode() && n->parentNode() == parent;) {
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<Node> nodeToRemove(n.release());
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        n = nodeToRemove->nextSibling();
1561fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        parent->removeChild(nodeToRemove.get(), IGNORE_EXCEPTION);
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (this != endText) {
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node* onePastEndText = endText->nextSibling();
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (RefPtr<Node> n = nextSibling(); n && n != onePastEndText && n->isTextNode() && n->parentNode() == parent;) {
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RefPtr<Node> nodeToRemove(n.release());
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            n = nodeToRemove->nextSibling();
1641fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch            parent->removeChild(nodeToRemove.get(), IGNORE_EXCEPTION);
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newText.isEmpty()) {
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (parent && parentNode() == parent)
1701fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch            parent->removeChild(this, IGNORE_EXCEPTION);
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
174521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    setData(newText);
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return protectedThis.release();
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String Text::nodeName() const
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return textAtom.string();
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node::NodeType Text::nodeType() const
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return TEXT_NODE;
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<Node> Text::cloneNode(bool /*deep*/)
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
19053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return cloneWithData(data());
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
193926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool Text::textRendererIsNeeded(const NodeRenderingContext& context)
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (isEditingText())
196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return true;
197926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
198926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!length())
199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return false;
200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (context.style()->display() == NONE)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    if (!containsOnlyWhitespace())
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* parent = context.parentRenderer();
20883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    if (!parent->canHaveWhitespaceChildren())
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
21002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (context.style()->preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
213e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* prev = context.previousRenderer();
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (prev && prev->isBR()) // <span><br/> <br/></span>
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
21702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (parent->isRenderInline()) {
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // <span><div/> <div/></span>
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (prev && !prev->isInline())
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (parent->isRenderBlock() && !parent->childrenInline() && (!prev || !prev->isInline()))
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
22583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
22683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch        // Avoiding creation of a Renderer for the text node is a non-essential memory optimization.
22783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch        // So to avoid blowing up on very wide DOMs, we limit the number of siblings to visit.
22883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch        unsigned maxSiblingsToVisit = 50;
22983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* first = parent->firstChild();
23183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch        while (first && first->isFloatingOrOutOfFlowPositioned() && maxSiblingsToVisit--)
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            first = first->nextSibling();
23383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch        if (!first || context.nextRenderer() == first)
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Whitespace at the start of a block just goes away.  Don't even
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // make a render object for this text.
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
241926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static bool isSVGShadowText(Text* text)
242926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
243926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Node* parentNode = text->parentNode();
244926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return parentNode->isShadowRoot() && toShadowRoot(parentNode)->host()->hasTagName(SVGNames::trefTag);
245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
246926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
247926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static bool isSVGText(Text* text)
248926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
249926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Node* parentOrShadowHostNode = text->parentOrShadowHostNode();
250926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return parentOrShadowHostNode->isSVGElement() && !parentOrShadowHostNode->hasTagName(SVGNames::foreignObjectTag);
251926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
252926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
253591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochRenderText* Text::createTextRenderer(RenderStyle* style)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (isSVGText(this) || isSVGShadowText(this))
256f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        return new RenderSVGInlineText(this, dataImpl());
25793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (style->hasTextCombine())
259f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        return new RenderCombineText(this, dataImpl());
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
261f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    return new RenderText(this, dataImpl());
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
264521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void Text::attach(const AttachContext& context)
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
266e6d4491e48613634a83c1957c72759da80987961Ben Murdoch    NodeRenderingContext(this, context.resolvedStyle).createRendererForTextIfNeeded();
267521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    CharacterData::attach(context);
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
270e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochbool Text::recalcTextStyle(StyleChange change)
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
272e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (RenderText* renderer = toRenderText(this->renderer())) {
273591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        if (change != NoChange || needsStyleRecalc())
274591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            renderer->setStyle(document()->styleResolver()->styleForText(this));
275521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if (needsStyleRecalc())
276591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            renderer->setText(dataImpl());
277e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        clearNeedsStyleRecalc();
278e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    } else if (needsStyleRecalc() || needsWhitespaceRenderer()) {
279591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        reattach();
280e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        return true;
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
282e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    return false;
283e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
284521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
285e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch// If a whitespace node had no renderer and goes through a recalcStyle it may
286e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch// need to create one if the parent style now has white-space: pre.
287e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochbool Text::needsWhitespaceRenderer()
288e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
289e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    ASSERT(!renderer());
29083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    if (RenderStyle* style = parentRenderStyle())
291e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        return style->preserveNewline();
292e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    return false;
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void Text::updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData)
296926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
2975267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (!attached())
298926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
299926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RenderText* textRenderer = toRenderText(renderer());
300926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!textRenderer || !textRendererIsNeeded(NodeRenderingContext(this, textRenderer->style()))) {
301926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        reattach();
302926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
303926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
304926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    textRenderer->setTextWithOffset(dataImpl(), offsetOfReplacedData, lengthOfReplacedData);
305926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
306926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Text::childTypeAllowed(NodeType) const
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
31253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)PassRefPtr<Text> Text::cloneWithData(const String& data)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return create(document(), data);
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)PassRefPtr<Text> Text::createWithLengthLimit(Document* document, const String& data, unsigned start, unsigned lengthLimit)
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned dataLength = data.length();
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (!start && dataLength <= lengthLimit)
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return create(document, data);
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Text> result = Text::create(document, String());
3255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    result->parserAppendData(data, start, lengthLimit);
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Text::formatForDebugger(char *buffer, unsigned length) const
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder result;
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String s;
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result.append(nodeName());
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    s = data();
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (s.length() > 0) {
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (result.length())
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result.appendLiteral("; ");
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.appendLiteral("value=");
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.append(s);
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    strncpy(buffer, result.toString().utf8().data(), length - 1);
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
351