Commit ff51b523 authored by ap@webkit.org's avatar ap@webkit.org
Browse files

Reviewed by Darin.

        http://bugs.webkit.org/show_bug.cgi?id=15896
        More editing cleanup

        No functionality changes.

        * dom/Node.h: Moved several editing-related methods elsewhere.
        * dom/Node.cpp: (WebCore::Node::maxCharacterOffset): Renamed from maxOffset()
        to highlight that it is a match to offsetInCharacters(), and much different from other
        offset-related methods. Added ASSERT_NOT_REACHED(), as callers are supposed to check
        offsetInCharacters() before calling this.

        * dom/CharacterData.cpp: (WebCore::CharacterData::maxCharacterOffset):
        * dom/CharacterData.h: (WebCore::CharacterData::isCharacterDataNode):
        Updated for above renamings.

        * dom/Comment.{h,cpp}: Removed an override for offsetInCharacters(), which is already present in CharacterData.

        * dom/Document.{h,cpp}: Folded updateSelection() into Frame::selectionLayoutChanged().

        * dom/Position.h:
        * dom/Position.cpp:
        (WebCore::Position::uncheckedPreviousOffset): Moved from Node::previousOffset().
        (WebCore::Position::uncheckedNextOffset): Moved from Node::NextOffset().
        (WebCore::Position::previous): Adapted to the above move.
        (WebCore::Position::next): Ditto.
        (WebCore::Position::upstream): Removed an isBR() check, since a non-BR element cannot have a BR renderer (I think),
        and BR elements are covered by editingIgnoresContent().
        (WebCore::Position::downstream): Ditto.
        (WebCore::caretMaxRenderedOffset): Moved from Node::caretMaxRenderedOffset().
        (WebCore::Position::rendersInDifferentPosition): Updated for the above moves.

        * dom/PositionIterator.h: Added a comment describing this class from the original check-in.
        * dom/PositionIterator.cpp:
        (WebCore::PositionIterator::increment): Updated for the above moves.
        (WebCore::PositionIterator::decrement): Ditto.

        * dom/ProcessingInstruction.h:
        * dom/ProcessingInstruction.cpp: (WebCore::ProcessingInstruction::maxCharacterOffset):
        ProcessingInstruction was already returning true from offsetInCharacters(), but didn't override maxCharacterOffset().
        I think that implementing it has no actual effect, as PIs are not rendered, but it looks cleaner this way.

        * dom/Range.cpp:
        (WebCore::Range::selectNodeContents):
        * editing/ApplyStyleCommand.cpp:
        (WebCore::ApplyStyleCommand::applyRelativeFontStyleChange):
        (WebCore::ApplyStyleCommand::applyInlineStyle):
        (WebCore::maxRangeOffset):
        (WebCore::ApplyStyleCommand::removeInlineStyle):
        (WebCore::ApplyStyleCommand::splitTextAtStartIfNeeded):
        (WebCore::ApplyStyleCommand::splitTextAtEndIfNeeded):
        (WebCore::ApplyStyleCommand::splitTextElementAtStartIfNeeded):
        (WebCore::ApplyStyleCommand::splitTextElementAtEndIfNeeded):
        (WebCore::ApplyStyleCommand::mergeEndWithNextIfIdentical):
        * editing/CompositeEditCommand.cpp:
        (WebCore::CompositeEditCommand::insertNodeAt):
        (WebCore::CompositeEditCommand::positionOutsideTabSpan):
        * editing/DeleteSelectionCommand.cpp:
        (WebCore::DeleteSelectionCommand::handleGeneralDelete):
        * editing/InsertLineBreakCommand.cpp:
        (WebCore::InsertLineBreakCommand::doApply):
        * editing/InsertParagraphSeparatorCommand.cpp:
        (WebCore::InsertParagraphSeparatorCommand::doApply):
        * editing/InsertTextCommand.cpp:
        (WebCore::InsertTextCommand::insertTab):
        * editing/visible_units.cpp:
        (WebCore::previousLinePosition):
        (WebCore::nextLinePosition):
        Updated for the above moves.

        * editing/Editor.cpp:
        (WebCore::Editor::advanceToNextMisspelling): Added a missing rangeCompliantEquivalent() call.

        * editing/TextIterator.cpp:
        (WebCore::SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator): Changed the condition to obviously
        match a maxCharacterOffset() call made after it; hopefully, this doesn't break any border cases.
        (WebCore::SimplifiedBackwardsTextIterator::advance): Updated for the above moves.

        * editing/htmlediting.h:
        * editing/htmlediting.cpp:
        (WebCore::canHaveChildrenForEditing): Removed a bogus comment: I don't thin BRs have a special ability to accept
        child nodes, other than via DOM manipulation, which is not specific to BRs.
        (WebCore::rangeCompliantEquivalent): Removed a check for BR, which is already covered by editingIgnoresContent().
        (WebCore::maxDeepOffset): Ditto.
        (WebCore::caretMinOffset): Moved from Node. Changed some runtime checks that seemingly cannot fail into assertions.
        (WebCore::caretMaxOffset): Ditto.

        * page/EventHandler.cpp:
        (WebCore::EventHandler::handleMousePressEventSingleClick): Pass 0 to VisiblePosition constructor instead of
        caretMinOffset. I didn't want to include htmlediting.h here, and I think that VisiblePosition constructor
        will take care of adjusting the offset.

        * page/Frame.cpp: (WebCore::Frame::selectionLayoutChanged): Folded Document::updateSelection() here.
        * page/mac/WebCoreFrameBridge.mm:
        (-[WebCoreFrameBridge smartDeleteRangeForProposedRange:]): Added missing rangeCompliantEquivalent() calls.
        * rendering/RenderBlock.cpp: (WebCore::RenderBlock::positionForRenderer): Changed to not round-trip via editing.
        Changed some runtime checks that seemingly cannot fail into assertions.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@27690 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 68af1ff4
2007-11-11 Alexey Proskuryakov <ap@nypop.com>
Reviewed by Darin.
http://bugs.webkit.org/show_bug.cgi?id=15896
More editing cleanup
No functionality changes.
* dom/Node.h: Moved several editing-related methods elsewhere.
* dom/Node.cpp: (WebCore::Node::maxCharacterOffset): Renamed from maxOffset()
to highlight that it is a match to offsetInCharacters(), and much different from other
offset-related methods. Added ASSERT_NOT_REACHED(), as callers are supposed to check
offsetInCharacters() before calling this.
* dom/CharacterData.cpp: (WebCore::CharacterData::maxCharacterOffset):
* dom/CharacterData.h: (WebCore::CharacterData::isCharacterDataNode):
Updated for above renamings.
* dom/Comment.{h,cpp}: Removed an override for offsetInCharacters(), which is already present in CharacterData.
* dom/Document.{h,cpp}: Folded updateSelection() into Frame::selectionLayoutChanged().
* dom/Position.h:
* dom/Position.cpp:
(WebCore::Position::uncheckedPreviousOffset): Moved from Node::previousOffset().
(WebCore::Position::uncheckedNextOffset): Moved from Node::NextOffset().
(WebCore::Position::previous): Adapted to the above move.
(WebCore::Position::next): Ditto.
(WebCore::Position::upstream): Removed an isBR() check, since a non-BR element cannot have a BR renderer (I think),
and BR elements are covered by editingIgnoresContent().
(WebCore::Position::downstream): Ditto.
(WebCore::caretMaxRenderedOffset): Moved from Node::caretMaxRenderedOffset().
(WebCore::Position::rendersInDifferentPosition): Updated for the above moves.
* dom/PositionIterator.h: Added a comment describing this class from the original check-in.
* dom/PositionIterator.cpp:
(WebCore::PositionIterator::increment): Updated for the above moves.
(WebCore::PositionIterator::decrement): Ditto.
* dom/ProcessingInstruction.h:
* dom/ProcessingInstruction.cpp: (WebCore::ProcessingInstruction::maxCharacterOffset):
ProcessingInstruction was already returning true from offsetInCharacters(), but didn't override maxCharacterOffset().
I think that implementing it has no actual effect, as PIs are not rendered, but it looks cleaner this way.
* dom/Range.cpp:
(WebCore::Range::selectNodeContents):
* editing/ApplyStyleCommand.cpp:
(WebCore::ApplyStyleCommand::applyRelativeFontStyleChange):
(WebCore::ApplyStyleCommand::applyInlineStyle):
(WebCore::maxRangeOffset):
(WebCore::ApplyStyleCommand::removeInlineStyle):
(WebCore::ApplyStyleCommand::splitTextAtStartIfNeeded):
(WebCore::ApplyStyleCommand::splitTextAtEndIfNeeded):
(WebCore::ApplyStyleCommand::splitTextElementAtStartIfNeeded):
(WebCore::ApplyStyleCommand::splitTextElementAtEndIfNeeded):
(WebCore::ApplyStyleCommand::mergeEndWithNextIfIdentical):
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::insertNodeAt):
(WebCore::CompositeEditCommand::positionOutsideTabSpan):
* editing/DeleteSelectionCommand.cpp:
(WebCore::DeleteSelectionCommand::handleGeneralDelete):
* editing/InsertLineBreakCommand.cpp:
(WebCore::InsertLineBreakCommand::doApply):
* editing/InsertParagraphSeparatorCommand.cpp:
(WebCore::InsertParagraphSeparatorCommand::doApply):
* editing/InsertTextCommand.cpp:
(WebCore::InsertTextCommand::insertTab):
* editing/visible_units.cpp:
(WebCore::previousLinePosition):
(WebCore::nextLinePosition):
Updated for the above moves.
* editing/Editor.cpp:
(WebCore::Editor::advanceToNextMisspelling): Added a missing rangeCompliantEquivalent() call.
* editing/TextIterator.cpp:
(WebCore::SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator): Changed the condition to obviously
match a maxCharacterOffset() call made after it; hopefully, this doesn't break any border cases.
(WebCore::SimplifiedBackwardsTextIterator::advance): Updated for the above moves.
* editing/htmlediting.h:
* editing/htmlediting.cpp:
(WebCore::canHaveChildrenForEditing): Removed a bogus comment: I don't thin BRs have a special ability to accept
child nodes, other than via DOM manipulation, which is not specific to BRs.
(WebCore::rangeCompliantEquivalent): Removed a check for BR, which is already covered by editingIgnoresContent().
(WebCore::maxDeepOffset): Ditto.
(WebCore::caretMinOffset): Moved from Node. Changed some runtime checks that seemingly cannot fail into assertions.
(WebCore::caretMaxOffset): Ditto.
* page/EventHandler.cpp:
(WebCore::EventHandler::handleMousePressEventSingleClick): Pass 0 to VisiblePosition constructor instead of
caretMinOffset. I didn't want to include htmlediting.h here, and I think that VisiblePosition constructor
will take care of adjusting the offset.
* page/Frame.cpp: (WebCore::Frame::selectionLayoutChanged): Folded Document::updateSelection() here.
* page/mac/WebCoreFrameBridge.mm:
(-[WebCoreFrameBridge smartDeleteRangeForProposedRange:]): Added missing rangeCompliantEquivalent() calls.
* rendering/RenderBlock.cpp: (WebCore::RenderBlock::positionForRenderer): Changed to not round-trip via editing.
Changed some runtime checks that seemingly cannot fail into assertions.
2007-11-11 Darin Adler <darin@apple.com>
Reviewed by Sam.
......
......@@ -259,29 +259,11 @@ void CharacterData::checkCharDataOperation( const unsigned offset, ExceptionCode
}
}
int CharacterData::maxOffset() const
int CharacterData::maxCharacterOffset() const
{
return (int)length();
}
int CharacterData::caretMinOffset() const
{
RenderText *r = static_cast<RenderText *>(renderer());
return r && r->isText() ? r->caretMinOffset() : 0;
}
int CharacterData::caretMaxOffset() const
{
RenderText *r = static_cast<RenderText *>(renderer());
return r && r->isText() ? r->caretMaxOffset() : (int)length();
}
unsigned CharacterData::caretMaxRenderedOffset() const
{
RenderText *r = static_cast<RenderText *>(renderer());
return r ? r->caretMaxRenderedOffset() : length();
}
bool CharacterData::rendererIsNeeded(RenderStyle *style)
{
if (!str || str->length() == 0)
......
......@@ -53,17 +53,14 @@ public:
virtual String nodeValue() const;
virtual void setNodeValue(const String&, ExceptionCode&);
virtual bool isCharacterDataNode() const { return true; }
// Other methods (not part of DOM)
virtual bool isCharacterDataNode() const { return true; }
virtual int maxCharacterOffset() const;
StringImpl* string() { return str; }
virtual void checkCharDataOperation(unsigned offset, ExceptionCode&);
virtual int maxOffset() const;
virtual int caretMinOffset() const;
virtual int caretMaxOffset() const;
virtual unsigned caretMaxRenderedOffset() const;
virtual bool offsetInCharacters() const;
virtual bool rendererIsNeeded(RenderStyle*);
......
......@@ -74,9 +74,4 @@ String Comment::toString() const
return "<!--" + nodeValue() + "-->";
}
bool Comment::offsetInCharacters() const
{
return true;
}
} // namespace WebCore
......@@ -45,7 +45,6 @@ public:
// Other methods (not part of DOM)
virtual bool isCommentNode() const { return true; }
virtual bool childTypeAllowed(NodeType);
virtual bool offsetInCharacters() const;
virtual String toString() const;
};
......
......@@ -1297,38 +1297,6 @@ void Document::setVisuallyOrdered()
renderer()->style()->setVisuallyOrdered(true);
}
void Document::updateSelection()
{
if (!renderer())
return;
RenderView *canvas = static_cast<RenderView*>(renderer());
Selection selection = frame()->selectionController()->selection();
if (!selection.isRange())
canvas->clearSelection();
else {
// Use the rightmost candidate for the start of the selection, and the leftmost candidate for the end of the selection.
// Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', and that 'bar' is selected. If we pass [foo, 3]
// as the start of the selection, the selection painting code will think that content on the line containing 'foo' is selected
// and will fill the gap before 'bar'.
Position startPos = selection.visibleStart().deepEquivalent();
if (startPos.downstream().isCandidate())
startPos = startPos.downstream();
Position endPos = selection.visibleEnd().deepEquivalent();
if (endPos.upstream().isCandidate())
endPos = endPos.upstream();
// We can get into a state where the selection endpoints map to the same VisiblePosition when a selection is deleted
// because we don't yet notify the SelectionController of text removal.
if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) {
RenderObject *startRenderer = startPos.node()->renderer();
RenderObject *endRenderer = endPos.node()->renderer();
static_cast<RenderView*>(renderer())->setSelection(startRenderer, startPos.offset(), endRenderer, endPos.offset());
}
}
}
Tokenizer* Document::createTokenizer()
{
// FIXME: this should probably pass the frame instead
......
......@@ -347,8 +347,6 @@ public:
// to get visually ordered hebrew and arabic pages right
void setVisuallyOrdered();
void updateSelection();
void open();
void implicitOpen();
void close();
......
......@@ -1067,38 +1067,14 @@ RenderStyle* Node::computedStyle()
return parent() ? parent()->computedStyle() : 0;
}
int Node::maxOffset() const
int Node::maxCharacterOffset() const
{
return 1;
ASSERT_NOT_REACHED();
return 0;
}
// FIXME: Shouldn't these functions be in the editing code? Code that asks questions about HTML in the core DOM class
// is obviously misplaced.
int Node::caretMinOffset() const
{
return renderer() ? renderer()->caretMinOffset() : 0;
}
int Node::caretMaxOffset() const
{
return renderer() ? renderer()->caretMaxOffset() : 1;
}
unsigned Node::caretMaxRenderedOffset() const
{
return renderer() ? renderer()->caretMaxRenderedOffset() : 1;
}
int Node::previousOffset (int current) const
{
return renderer() ? renderer()->previousOffset(current) : current - 1;
}
int Node::nextOffset (int current) const
{
return renderer() ? renderer()->nextOffset(current) : current + 1;
}
bool Node::canStartSelection() const
{
if (isContentEditable())
......
......@@ -349,14 +349,9 @@ public:
// Used to determine whether range offsets use characters or node indices.
virtual bool offsetInCharacters() const;
// FIXME: These next 7 functions are mostly editing-specific and should be moved out.
virtual int maxOffset() const;
virtual int caretMinOffset() const;
virtual int caretMaxOffset() const;
virtual unsigned caretMaxRenderedOffset() const;
virtual int previousOffset(int current) const;
virtual int nextOffset(int current) const;
// Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of
// css-transform:capitalize breaking up precomposed characters and ligatures.
virtual int maxCharacterOffset() const;
// FIXME: We should try to find a better location for these methods.
virtual bool canSelectAll() const { return false; }
......
......@@ -133,7 +133,7 @@ Position Position::previous(EUsingComposedCharacters usingComposedCharacters) co
// Going backward one character at a time is correct.
// 2) The old offset was a bogus offset like (<br>, 1), and there is no child.
// Going from 1 to 0 is correct.
return Position(n, usingComposedCharacters ? n->previousOffset(o) : o - 1);
return Position(n, usingComposedCharacters ? uncheckedPreviousOffset(n, o) : o - 1);
}
Node *parent = n->parentNode();
......@@ -163,7 +163,7 @@ Position Position::next(EUsingComposedCharacters usingComposedCharacters) const
// Going forward one character at a time is correct.
// 2) The new offset is a bogus offset like (<br>, 1), and there is no child.
// Going from 0 to 1 is correct.
return Position(n, usingComposedCharacters ? n->nextOffset(o) : o + 1);
return Position(n, usingComposedCharacters ? uncheckedNextOffset(n, o) : o + 1);
}
Node *parent = n->parentNode();
......@@ -173,6 +173,16 @@ Position Position::next(EUsingComposedCharacters usingComposedCharacters) const
return Position(parent, n->nodeIndex() + 1);
}
int Position::uncheckedPreviousOffset(const Node* n, int current)
{
return n->renderer() ? n->renderer()->previousOffset(current) : current - 1;
}
int Position::uncheckedNextOffset(const Node* n, int current)
{
return n->renderer() ? n->renderer()->nextOffset(current) : current + 1;
}
bool Position::atStart() const
{
Node *n = node();
......@@ -320,9 +330,9 @@ Position Position::upstream() const
// return lastVisible on the next iteration, but we terminate early.
if (currentNode == enclosingBlock(currentNode) && currentPos.atStartOfNode())
return lastVisible;
// Return position after brs, tables, and nodes which have content that can be ignored.
if (editingIgnoresContent(currentNode) || renderer->isBR() || isTableElement(currentNode)) {
// Return position after tables and nodes which have content that can be ignored.
if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
if (currentPos.atEndOfNode())
return Position(currentNode, maxDeepOffset(currentNode));
continue;
......@@ -392,8 +402,8 @@ Position Position::downstream() const
if (isStreamer(currentPos))
lastVisible = currentPos;
// Return position before brs, tables, and nodes which have content that can be ignored.
if (editingIgnoresContent(currentNode) || renderer->isBR() || isTableElement(currentNode)) {
// Return position before tables and nodes which have content that can be ignored.
if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
if (currentPos.offsetInLeafNode() <= renderer->caretMinOffset())
return Position(currentNode, renderer->caretMinOffset());
continue;
......@@ -493,6 +503,17 @@ bool Position::inRenderedText() const
return false;
}
static unsigned caretMaxRenderedOffset(const Node* n)
{
RenderObject* r = n->renderer();
if (r)
return r->caretMaxRenderedOffset();
if (n->isCharacterDataNode())
return static_cast<const CharacterData*>(n)->length();
return 1;
}
bool Position::isRenderedCharacter() const
{
if (isNull() || !node()->isTextNode())
......@@ -572,8 +593,8 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
LOG(Editing, "thisRenderedOffset: %d\n", thisRenderedOffset);
LOG(Editing, "posRenderer: %p [%p]\n", posRenderer, posRenderer ? posRenderer->inlineBox(offset()) : 0);
LOG(Editing, "posRenderedOffset: %d\n", posRenderedOffset);
LOG(Editing, "node min/max: %d:%d\n", node()->caretMinOffset(), node()->caretMaxRenderedOffset());
LOG(Editing, "pos node min/max: %d:%d\n", pos.node()->caretMinOffset(), pos.node()->caretMaxRenderedOffset());
LOG(Editing, "node min/max: %d:%d\n", caretMinOffset(node()), caretMaxRenderedOffset(node()));
LOG(Editing, "pos node min/max: %d:%d\n", caretMinOffset(pos.node()), caretMaxRenderedOffset(pos.node()));
LOG(Editing, "----------------------------------------------------------------------\n");
InlineBox *b1 = renderer ? renderer->inlineBox(offset()) : 0;
......@@ -588,19 +609,19 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
}
if (nextRenderedEditable(node()) == pos.node() &&
thisRenderedOffset == (int)node()->caretMaxRenderedOffset() && posRenderedOffset == 0) {
thisRenderedOffset == (int)caretMaxRenderedOffset(node()) && posRenderedOffset == 0) {
return false;
}
if (previousRenderedEditable(node()) == pos.node() &&
thisRenderedOffset == 0 && posRenderedOffset == (int)pos.node()->caretMaxRenderedOffset()) {
thisRenderedOffset == 0 && posRenderedOffset == (int)caretMaxRenderedOffset(pos.node())) {
return false;
}
return true;
}
// This is only called from DeleteSelectionCommand and assumes that it starts in editable content.
// This assumes that it starts in editable content.
Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNonCollapsibleWhitespace) const
{
ASSERT(isEditablePosition(*this));
......@@ -622,7 +643,7 @@ Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNo
return Position();
}
// This is only called from DeleteSelectionCommand and assumes that it starts in editable content.
// This assumes that it starts in editable content.
Position Position::trailingWhitespacePosition(EAffinity affinity, bool considerNonCollapsibleWhitespace) const
{
ASSERT(isEditablePosition(*this));
......
......@@ -57,12 +57,17 @@ public:
Element* element() const;
PassRefPtr<CSSComputedStyleDeclaration> computedStyle() const;
// Move up or down the DOM by one position
// Move up or down the DOM by one position.
// Offsets are computed using render text for nodes that have renderers - but note that even when
// using composed characters, the result may be inside a single user-visible character if a ligature is formed.
Position previous(EUsingComposedCharacters usingComposedCharacters=NotUsingComposedCharacters) const;
Position next(EUsingComposedCharacters usingComposedCharacters=NotUsingComposedCharacters) const;
static int uncheckedPreviousOffset(const Node*, int current);
static int uncheckedNextOffset(const Node*, int current);
bool atStart() const;
bool atEnd() const;
// FIXME: Make these non-member functions and put them somewhere in the editing directory.
// These aren't really basic "position" operations. More high level editing helper functions.
Position leadingWhitespacePosition(EAffinity, bool considerNonCollapsibleWhitespace = false) const;
......
......@@ -47,7 +47,7 @@ void PositionIterator::increment()
}
if (!m_parent->hasChildNodes() && m_offset < maxDeepOffset(m_parent))
m_offset = m_parent->nextOffset(m_offset);
m_offset = Position::uncheckedNextOffset(m_parent, m_offset);
else {
m_child = m_parent;
m_parent = m_child->parentNode();
......@@ -75,7 +75,7 @@ void PositionIterator::decrement()
}
if (m_offset) {
m_offset = m_parent->previousOffset(m_offset);
m_offset = Position::uncheckedPreviousOffset(m_parent, m_offset);
} else {
if (m_parent->hasChildNodes()) {
m_parent = m_parent->lastChild();
......
......@@ -30,6 +30,9 @@
namespace WebCore {
// A Position iterator with constant-time
// increment, decrement, and several predicates on the Position it is at.
// Conversion to/from Position is O(n) in the offset.
class PositionIterator {
public:
PositionIterator()
......
......@@ -248,4 +248,9 @@ bool ProcessingInstruction::offsetInCharacters() const
return true;
}
int ProcessingInstruction::maxCharacterOffset() const
{
return static_cast<int>(m_data.length());
}
} // namespace
......@@ -51,6 +51,7 @@ public:
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual bool childTypeAllowed(NodeType);
virtual bool offsetInCharacters() const;
virtual int maxCharacterOffset() const;
// Other methods (not part of DOM)
String localHref() const { return m_localHref; }
......
......@@ -1347,7 +1347,7 @@ void Range::selectNodeContents( Node *refNode, ExceptionCode& ec)
m_startContainer = refNode;
m_startOffset = 0;
m_endContainer = refNode;
m_endOffset = refNode->offsetInCharacters() ? refNode->maxOffset() : refNode->childNodeCount();
m_endOffset = refNode->offsetInCharacters() ? refNode->maxCharacterOffset() : refNode->childNodeCount();
}
void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionCode& ec)
......
......@@ -491,7 +491,7 @@ void ApplyStyleCommand::applyRelativeFontStyleChange(CSSMutableStyleDeclaration
start = start.upstream(); // Move upstream to ensure we do not add redundant spans.
Node *startNode = start.node();
if (startNode->isTextNode() && start.offset() >= startNode->caretMaxOffset()) // Move out of text node if range does not include its characters.
if (startNode->isTextNode() && start.offset() >= caretMaxOffset(startNode)) // Move out of text node if range does not include its characters.
startNode = startNode->traverseNextNode();
// Store away font size before making any changes to the document.
......@@ -643,7 +643,7 @@ void ApplyStyleCommand::applyInlineStyle(CSSMutableStyleDeclaration *style)
bool rangeIsEmpty = false;
if (start.offset() >= start.node()->caretMaxOffset()) {
if (start.offset() >= caretMaxOffset(start.node())) {
node = node->traverseNextNode();
Position newStart = Position(node, 0);
if (Range::compareBoundaryPoints(end, newStart) < 0)
......@@ -949,7 +949,7 @@ void ApplyStyleCommand::pushDownTextDecorationStyleAtBoundaries(const Position &
static int maxRangeOffset(Node *n)
{
if (n->offsetInCharacters())
return n->maxOffset();
return n->maxCharacterOffset();
if (n->isElementNode())
return n->childNodeCount();
......@@ -998,7 +998,7 @@ void ApplyStyleCommand::removeInlineStyle(PassRefPtr<CSSMutableStyleDeclaration>
if (s.node() == elem) {
// Since elem must have been fully selected, and it is at the start
// of the selection, it is clear we can set the new s offset to 0.
ASSERT(s.offset() <= s.node()->caretMinOffset());
ASSERT(s.offset() <= caretMinOffset(s.node()));
s = Position(next, 0);
}
if (e.node() == elem) {
......@@ -1045,7 +1045,7 @@ bool ApplyStyleCommand::nodeFullyUnselected(Node *node, const Position &start, c
bool ApplyStyleCommand::splitTextAtStartIfNeeded(const Position &start, const Position &end)
{
if (start.node()->isTextNode() && start.offset() > start.node()->caretMinOffset() && start.offset() < start.node()->caretMaxOffset()) {
if (start.node()->isTextNode() && start.offset() > caretMinOffset(start.node()) && start.offset() < caretMaxOffset(start.node())) {
int endOffsetAdjustment = start.node() == end.node() ? start.offset() : 0;
Text *text = static_cast<Text *>(start.node());
splitTextNode(text, start.offset());
......@@ -1057,7 +1057,7 @@ bool ApplyStyleCommand::splitTextAtStartIfNeeded(const Position &start, const Po
bool ApplyStyleCommand::splitTextAtEndIfNeeded(const Position &start, const Position &end)
{
if (end.node()->isTextNode() && end.offset() > end.node()->caretMinOffset() && end.offset() < end.node()->caretMaxOffset()) {
if (end.node()->isTextNode() && end.offset() > caretMinOffset(end.node()) && end.offset() < caretMaxOffset(end.node())) {
Text *text = static_cast<Text *>(end.node());
splitTextNode(text, end.offset());
......@@ -1065,7 +1065,7 @@ bool ApplyStyleCommand::splitTextAtEndIfNeeded(const Position &start, const Posi
ASSERT(prevNode);
Node *startNode = start.node() == end.node() ? prevNode : start.node();
ASSERT(startNode);
updateStartEnd(Position(startNode, start.offset()), Position(prevNode, prevNode->caretMaxOffset()));
updateStartEnd(Position(startNode, start.offset()), Position(prevNode, caretMaxOffset(prevNode)));
return true;
}
return false;
......@@ -1073,7 +1073,7 @@ bool ApplyStyleCommand::splitTextAtEndIfNeeded(const Position &start, const Posi
bool ApplyStyleCommand::splitTextElementAtStartIfNeeded(const Position &start, const Position &end)
{
if (start.node()->isTextNode() && start.offset() > start.node()->caretMinOffset() && start.offset() < start.node()->caretMaxOffset()) {
if (start.node()->isTextNode() && start.offset() > caretMinOffset(start.node()) && start.offset() < caretMaxOffset(start.node())) {
int endOffsetAdjustment = start.node() == end.node() ? start.offset() : 0;
Text *text = static_cast<Text *>(start.node());
splitTextNodeContainingElement(text, start.offset());
......@@ -1086,7 +1086,7 @@ bool ApplyStyleCommand::splitTextElementAtStartIfNeeded(const Position &start, c
bool ApplyStyleCommand::splitTextElementAtEndIfNeeded(const Position &start, const Position &end)
{
if (end.node()->isTextNode() && end.offset() > end.node()->caretMinOffset() && end.offset() < end.node()->caretMaxOffset()) {
if (end.node()->isTextNode() && end.offset() > caretMinOffset(end.node()) && end.offset() < caretMaxOffset(end.node())) {
Text *text = static_cast<Text *>(end.node());
splitTextNodeContainingElement(text, end.offset());
......@@ -1183,7 +1183,7 @@ bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position &start, const
int endOffset = end.offset();
if (isAtomicNode(endNode)) {
if (endOffset < endNode->caretMaxOffset())
if (endOffset < caretMaxOffset(endNode))
return false;
unsigned parentLastOffset = end.node()->parent()->childNodes()->length() - 1;
......
......@@ -156,9 +156,9 @@ void CompositeEditCommand::insertNodeAt(Node* insertChild, const Position& editi
insertNodeBefore(insertChild, child);
else
appendNode(insertChild, refChild);
} else if (refChild->caretMinOffset() >= offset) {
} else if (caretMinOffset(refChild) >= offset) {
insertNodeBefore(insertChild, refChild);
} else if (refChild->isTextNode() && refChild->caretMaxOffset() > offset) {
} else if (refChild->isTextNode() && caretMaxOffset(refChild) > offset) {
splitTextNode(static_cast<Text *>(refChild), offset);
insertNodeBefore(insertChild, refChild);
} else {
......@@ -290,10 +290,10 @@ Position CompositeEditCommand::positionOutsideTabSpan(const Position& pos)
Node* tabSpan = tabSpanNode(pos.node());
if (pos.offset() <= pos.node()->caretMinOffset())
if (pos.offset() <= caretMinOffset(pos.node()))
return positionBeforeNode(tabSpan);
if (pos.offset() >= pos.node()->caretMaxOffset())
if (pos.offset() >= caretMaxOffset(pos.node()))
return positionAfterNode(tabSpan);
splitTextNodeContainingElement(static_cast<Text *>(pos.node()), pos.offset());
......