diff options
Diffstat (limited to 'WebCore/dom/Text.cpp')
-rw-r--r-- | WebCore/dom/Text.cpp | 87 |
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 += "; "; |