summaryrefslogtreecommitdiffstats
path: root/WebCore/dom/Text.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/dom/Text.cpp')
-rw-r--r--WebCore/dom/Text.cpp87
1 files changed, 45 insertions, 42 deletions
diff --git a/WebCore/dom/Text.cpp b/WebCore/dom/Text.cpp
index bbd926b..1ce074a 100644
--- a/WebCore/dom/Text.cpp
+++ b/WebCore/dom/Text.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -37,22 +37,18 @@
#include "WMLVariables.h"
#endif
-namespace WebCore {
-
-// DOM Section 1.1.1
+using namespace std;
-Text::Text(Document* document, const String& text)
- : CharacterData(document, text, true)
-{
-}
+namespace WebCore {
-Text::Text(Document* document)
- : CharacterData(document, true)
+Text::Text(Document* document, const String& data)
+ : CharacterData(document, data, CreateText)
{
}
-Text::~Text()
+PassRefPtr<Text> Text::create(Document* document, const String& data)
{
+ return adoptRef(new Text(document, data));
}
PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionCode& ec)
@@ -61,14 +57,14 @@ PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionCode& ec)
// INDEX_SIZE_ERR: Raised if the specified offset is negative or greater than
// the number of 16-bit units in data.
- if (offset > m_data->length()) {
+ if (offset > length()) {
ec = INDEX_SIZE_ERR;
return 0;
}
- RefPtr<StringImpl> oldStr = m_data;
- RefPtr<Text> newText = createNew(oldStr->substring(offset));
- m_data = oldStr->substring(0, offset);
+ RefPtr<StringImpl> oldStr = dataImpl();
+ RefPtr<Text> newText = virtualCreate(oldStr->substring(offset));
+ setDataImpl(oldStr->substring(0, offset));
dispatchModifiedEvent(oldStr.get());
@@ -81,7 +77,7 @@ PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionCode& ec)
document()->textNodeSplit(this);
if (renderer())
- toRenderText(renderer())->setText(m_data);
+ toRenderText(renderer())->setText(dataImpl());
return newText.release();
}
@@ -199,7 +195,7 @@ Node::NodeType Text::nodeType() const
PassRefPtr<Node> Text::cloneNode(bool /*deep*/)
{
- return document()->createTextNode(m_data);
+ return create(document(), data());
}
bool Text::rendererIsNeeded(RenderStyle *style)
@@ -244,7 +240,7 @@ bool Text::rendererIsNeeded(RenderStyle *style)
return true;
}
-RenderObject *Text::createRenderer(RenderArena* arena, RenderStyle*)
+RenderObject* Text::createRenderer(RenderArena* arena, RenderStyle*)
{
#if ENABLE(SVG)
if (parentNode()->isSVGElement()
@@ -252,17 +248,17 @@ RenderObject *Text::createRenderer(RenderArena* arena, RenderStyle*)
&& !parentNode()->hasTagName(SVGNames::foreignObjectTag)
#endif
)
- return new (arena) RenderSVGInlineText(this, m_data);
+ return new (arena) RenderSVGInlineText(this, dataImpl());
#endif
- return new (arena) RenderText(this, m_data);
+ return new (arena) RenderText(this, dataImpl());
}
void Text::attach()
{
#if ENABLE(WML)
if (document()->isWMLDocument() && !containsOnlyWhitespace()) {
- String text = m_data;
+ String text = data();
ASSERT(!text.isEmpty());
text = substituteVariableReferences(text, document());
@@ -286,7 +282,7 @@ void Text::recalcStyle(StyleChange change)
if (needsStyleRecalc()) {
if (renderer()) {
if (renderer()->isText())
- toRenderText(renderer())->setText(m_data);
+ toRenderText(renderer())->setText(dataImpl());
} else {
if (attached())
detach();
@@ -296,40 +292,47 @@ void Text::recalcStyle(StyleChange change)
setNeedsStyleRecalc(NoStyleChange);
}
-// DOM Section 1.1.1
bool Text::childTypeAllowed(NodeType)
{
return false;
}
-PassRefPtr<Text> Text::createNew(PassRefPtr<StringImpl> string)
+PassRefPtr<Text> Text::virtualCreate(const String& data)
{
- return new Text(document(), string);
+ return create(document(), data);
}
-PassRefPtr<Text> Text::createWithLengthLimit(Document* doc, const String& text, unsigned& charsLeft, unsigned maxChars)
+PassRefPtr<Text> Text::createWithLengthLimit(Document* document, const String& data, unsigned& charsLeft, unsigned maxChars)
{
- if (charsLeft == text.length() && charsLeft <= maxChars) {
+ unsigned dataLength = data.length();
+
+ if (charsLeft == dataLength && charsLeft <= maxChars) {
charsLeft = 0;
- return new Text(doc, text);
+ return create(document, data);
}
+
+ unsigned start = dataLength - charsLeft;
+ unsigned end = start + min(charsLeft, maxChars);
- unsigned start = text.length() - charsLeft;
- unsigned end = start + std::min(charsLeft, maxChars);
+ // Check we are not on an unbreakable boundary.
+ // Some text break iterator implementations work best if the passed buffer is as small as possible,
+ // see <https://bugs.webkit.org/show_bug.cgi?id=29092>.
+ // We need at least two characters look-ahead to account for UTF-16 surrogates.
+ if (end < dataLength) {
+ TextBreakIterator* it = characterBreakIterator(data.characters() + start, (end + 2 > dataLength) ? dataLength - start : end - start + 2);
+ if (!isTextBreak(it, end - start))
+ end = textBreakPreceding(it, end - start) + start;
+ }
- // check we are not on an unbreakable boundary
- TextBreakIterator* it = characterBreakIterator(text.characters(), text.length());
- if (end < text.length() && !isTextBreak(it, end))
- end = textBreakPreceding(it, end);
-
- // maxChars of unbreakable characters could lead to infinite loop
+ // If we have maxChars of unbreakable characters the above could lead to
+ // an infinite loop.
+ // FIXME: It would be better to just have the old value of end before calling
+ // textBreakPreceding rather than this, because this exceeds the length limit.
if (end <= start)
- end = text.length();
+ end = dataLength;
- String nodeText = text.substring(start, end - start);
- charsLeft = text.length() - end;
-
- return new Text(doc, nodeText);
+ charsLeft = dataLength - end;
+ return create(document, data.substring(start, end - start));
}
#ifndef NDEBUG
@@ -343,7 +346,7 @@ void Text::formatForDebugger(char *buffer, unsigned length) const
result += s;
}
- s = nodeValue();
+ s = data();
if (s.length() > 0) {
if (result.length() > 0)
result += "; ";