Diff
Modified: trunk/Source/WebCore/ChangeLog (89951 => 89952)
--- trunk/Source/WebCore/ChangeLog 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/ChangeLog 2011-06-28 20:07:31 UTC (rev 89952)
@@ -1,3 +1,60 @@
+2011-06-28 Ryosuke Niwa <[email protected]>
+
+ Reviewed by Darin Adler.
+
+ Stop instantiating Position with PositionIsOffsetInAnchor in various files
+ https://bugs.webkit.org/show_bug.cgi?id=63384
+
+ Refactoring.
+
+ Removed many if conditions that compared the anchor type to Position::PositionIsOffsetInAnchor
+ because there were also checking that containerNode is a text node.
+
+ Also added Position::containerText() to avoid manually casting containerNode().
+
+ * dom/Position.cpp:
+ (WebCore::Position::Position): Added an assertion to ensure BeforeChildren/AfterChildren
+ anchor type won't be used for a node whose contents is ignored by editing.
+ (WebCore::Position::containerText): Added.
+ * dom/Position.h:
+ * editing/ApplyBlockElementCommand.cpp:
+ (WebCore::isNewLineAtPosition): Removed a redundant comparison of anchor type.
+ (WebCore::ApplyBlockElementCommand::rangeForParagraphSplittingTextNodesIfNeeded): Since containerNode
+ is always a text node when renderStyleOfEnclosingTextNode returns a render style, use new Position
+ constructor that takes Text* and offset.
+ (WebCore::ApplyBlockElementCommand::endOfNextParagrahSplittingTextNodesIfNeeded): Removed redundant
+ comparison of anchor type and use new Position constructor that takes Text* and offset.
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::ApplyStyleCommand::splitTextAtStart): Replaced an assertion that compared anchor type by
+ an assertion that the container node is a text node; use new constructor.
+ (WebCore::ApplyStyleCommand::splitTextAtEnd): Ditto; also added early exits in the case script
+ modified DOM.
+ (WebCore::ApplyStyleCommand::splitTextElementAtStart): Ditto.
+ (WebCore::ApplyStyleCommand::splitTextElementAtEnd): Ditto.
+ (WebCore::ApplyStyleCommand::joinChildTextNodes): Use new constructor.
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::Editor::replaceSelectedTextInNode): Calls containerText instead of manually casting containerNode.
+ * editing/Editor.cpp:
+ (WebCore::Editor::canDeleteRange): Call Range::startPosition instead of manually instantiating Position
+ by calling startContainer and startOffset.
+ * editing/FrameSelection.cpp:
+ (WebCore::FrameSelection::setSelectedRange): Ditto.
+ * editing/InsertTextCommand.cpp:
+ (WebCore::InsertTextCommand::input): Calls containerText instead of manually casting containerNode.
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplaceSelectionCommand::doApply): Calls containerText instead of manually casting containerNode.
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::characterAfter): Removed a redundant anchor type comparison.
+ (WebCore::startVisiblePosition): Call Range::startPosition instead of startContainer and startOffset.
+ (WebCore::endVisiblePosition): Call Range::endPosition instead of endContainer and endOffset.
+ * editing/htmlediting.cpp:
+ (WebCore::firstInSpecialElement): Call containerNode() to address <rdar://problem/5027702>.
+ (WebCore::lastInSpecialElement): Ditto; use new constructor.
+ * editing/visible_units.cpp:
+ (WebCore::endPositionForLine): Use new constructor.
+ (WebCore::startOfParagraph): Ditto.
+ (WebCore::endOfParagraph): Ditto.
+
2011-06-28 Rob Buis <[email protected]>
Reviewed by Nikolas Zimmermann.
Modified: trunk/Source/WebCore/dom/Position.cpp (89951 => 89952)
--- trunk/Source/WebCore/dom/Position.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/dom/Position.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -91,7 +91,8 @@
{
ASSERT(!m_anchorNode || !m_anchorNode->isShadowRoot());
ASSERT(anchorType != PositionIsOffsetInAnchor);
- ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIsAfterChildren) && m_anchorNode->isTextNode()));
+ ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIsAfterChildren)
+ && (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNode.get()))));
}
Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorType)
@@ -148,6 +149,23 @@
return 0;
}
+Text* Position::containerText() const
+{
+ switch (anchorType()) {
+ case PositionIsOffsetInAnchor:
+ return m_anchorNode && m_anchorNode->isTextNode() ? static_cast<Text*>(m_anchorNode.get()) : 0;
+ case PositionIsBeforeAnchor:
+ case PositionIsAfterAnchor:
+ return 0;
+ case PositionIsBeforeChildren:
+ case PositionIsAfterChildren:
+ ASSERT(!m_anchorNode || !m_anchorNode->isTextNode());
+ return 0;
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
int Position::computeOffsetInContainerNode() const
{
if (!m_anchorNode)
Modified: trunk/Source/WebCore/dom/Position.h (89951 => 89952)
--- trunk/Source/WebCore/dom/Position.h 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/dom/Position.h 2011-06-28 20:07:31 UTC (rev 89952)
@@ -96,6 +96,8 @@
// These are always DOM compliant values. Editing positions like [img, 0] (aka [img, before])
// will return img->parentNode() and img->nodeIndex() from these functions.
Node* containerNode() const; // NULL for a before/after position anchored to a node with no parent
+ Text* containerText() const;
+
int computeOffsetInContainerNode() const; // O(n) for before/after-anchored positions, O(1) for parent-anchored positions
Position parentAnchoredEquivalent() const; // Convenience method for DOM positions that also fixes up some positions for editing
Modified: trunk/Source/WebCore/editing/ApplyBlockElementCommand.cpp (89951 => 89952)
--- trunk/Source/WebCore/editing/ApplyBlockElementCommand.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/ApplyBlockElementCommand.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -150,9 +150,6 @@
static bool isNewLineAtPosition(const Position& position)
{
- if (position.anchorType() != Position::PositionIsOffsetInAnchor)
- return false;
-
Node* textNode = position.containerNode();
int offset = position.offsetInContainerNode();
if (!textNode || !textNode->isTextNode() || offset < 0 || offset >= textNode->maxCharacterOffset())
@@ -181,11 +178,10 @@
start = startOfParagraph(endOfCurrentParagraph).deepEquivalent();
end = endOfCurrentParagraph.deepEquivalent();
- RenderStyle* startStyle = renderStyleOfEnclosingTextNode(start);
bool isStartAndEndOnSameNode = false;
- if (startStyle) {
- isStartAndEndOnSameNode = renderStyleOfEnclosingTextNode(end) && start.deprecatedNode() == end.deprecatedNode();
- bool isStartAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && start.deprecatedNode() == m_endOfLastParagraph.deprecatedNode();
+ if (RenderStyle* startStyle = renderStyleOfEnclosingTextNode(start)) {
+ isStartAndEndOnSameNode = renderStyleOfEnclosingTextNode(end) && start.containerNode() == end.containerNode();
+ bool isStartAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && start.containerNode() == m_endOfLastParagraph.containerNode();
// Avoid obtanining the start of next paragraph for start
if (startStyle->preserveNewline() && isNewLineAtPosition(start) && !isNewLineAtPosition(start.previous()) && start.offsetInContainerNode() > 0)
@@ -194,47 +190,44 @@
// If start is in the middle of a text node, split.
if (!startStyle->collapseWhiteSpace() && start.offsetInContainerNode() > 0) {
int startOffset = start.offsetInContainerNode();
- splitTextNode(static_cast<Text*>(start.deprecatedNode()), startOffset);
- start = firstPositionInOrBeforeNode(start.deprecatedNode());
+ Text* startText = start.containerText();
+ splitTextNode(startText, startOffset);
+ start = firstPositionInNode(startText);
if (isStartAndEndOnSameNode) {
ASSERT(end.offsetInContainerNode() >= startOffset);
- end = Position(end.deprecatedNode(), end.offsetInContainerNode() - startOffset, Position::PositionIsOffsetInAnchor);
+ end = Position(startText, end.offsetInContainerNode() - startOffset);
}
if (isStartAndEndOfLastParagraphOnSameNode) {
ASSERT(m_endOfLastParagraph.offsetInContainerNode() >= startOffset);
- m_endOfLastParagraph = Position(m_endOfLastParagraph.deprecatedNode(), m_endOfLastParagraph.offsetInContainerNode() - startOffset,
- Position::PositionIsOffsetInAnchor);
+ m_endOfLastParagraph = Position(startText, m_endOfLastParagraph.offsetInContainerNode() - startOffset);
}
}
}
- RenderStyle* endStyle = renderStyleOfEnclosingTextNode(end);
- if (endStyle) {
+ if (RenderStyle* endStyle = renderStyleOfEnclosingTextNode(end)) {
bool isEndAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && end.deprecatedNode() == m_endOfLastParagraph.deprecatedNode();
// Include \n at the end of line if we're at an empty paragraph
- if (endStyle->preserveNewline() && start == end
- && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {
+ if (endStyle->preserveNewline() && start == end && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {
int endOffset = end.offsetInContainerNode();
if (!isNewLineAtPosition(end.previous()) && isNewLineAtPosition(end))
- end = Position(end.deprecatedNode(), endOffset + 1, Position::PositionIsOffsetInAnchor);
+ end = Position(end.containerText(), endOffset + 1);
if (isEndAndEndOfLastParagraphOnSameNode && end.offsetInContainerNode() >= m_endOfLastParagraph.offsetInContainerNode())
m_endOfLastParagraph = end;
}
// If end is in the middle of a text node, split.
- if (!endStyle->collapseWhiteSpace() && end.offsetInContainerNode()
- && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {
- splitTextNode(static_cast<Text*>(end.deprecatedNode()), end.offsetInContainerNode());
+ if (!endStyle->collapseWhiteSpace() && end.offsetInContainerNode() && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {
+ RefPtr<Text> endContainer = end.containerText();
+ splitTextNode(endContainer, end.offsetInContainerNode());
if (isStartAndEndOnSameNode)
- start = firstPositionInOrBeforeNode(end.deprecatedNode()->previousSibling());
+ start = firstPositionInOrBeforeNode(endContainer->previousSibling());
if (isEndAndEndOfLastParagraphOnSameNode) {
if (m_endOfLastParagraph.offsetInContainerNode() == end.offsetInContainerNode())
- m_endOfLastParagraph = lastPositionInNode(end.deprecatedNode()->previousSibling());
+ m_endOfLastParagraph = lastPositionInOrAfterNode(endContainer->previousSibling());
else
- m_endOfLastParagraph = Position(end.deprecatedNode(), m_endOfLastParagraph.offsetInContainerNode() - end.offsetInContainerNode(),
- Position::PositionIsOffsetInAnchor);
+ m_endOfLastParagraph = Position(endContainer, m_endOfLastParagraph.offsetInContainerNode() - end.offsetInContainerNode());
}
- end = lastPositionInNode(end.deprecatedNode()->previousSibling());
+ end = lastPositionInNode(endContainer->previousSibling());
}
}
}
@@ -247,32 +240,34 @@
if (!style)
return endOfNextParagraph;
- RefPtr<Node> containerNode = position.containerNode();
- if (!style->preserveNewline() || !position.offsetInContainerNode()
- || !isNewLineAtPosition(Position(containerNode.get(), 0, Position::PositionIsOffsetInAnchor)))
+ RefPtr<Text> text = position.containerText();
+ if (!style->preserveNewline() || !position.offsetInContainerNode() || !isNewLineAtPosition(firstPositionInNode(text.get())))
return endOfNextParagraph;
// \n at the beginning of the text node immediately following the current paragraph is trimmed by moveParagraphWithClones.
// If endOfNextParagraph was pointing at this same text node, endOfNextParagraph will be shifted by one paragraph.
// Avoid this by splitting "\n"
- splitTextNode(static_cast<Text*>(containerNode.get()), 1);
+ splitTextNode(text, 1);
- if (start.anchorType() == Position::PositionIsOffsetInAnchor && containerNode.get() == start.containerNode()) {
+ if (text == start.containerNode() && text->previousSibling() && text->previousSibling()->isTextNode()) {
ASSERT(start.offsetInContainerNode() < position.offsetInContainerNode());
- start = Position(containerNode->previousSibling(), start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+ start = Position(static_cast<Text*>(text->previousSibling()), start.offsetInContainerNode());
}
- if (end.anchorType() == Position::PositionIsOffsetInAnchor && containerNode.get() == end.containerNode()) {
+ if (text == end.containerNode() && text->previousSibling() && text->previousSibling()->isTextNode()) {
ASSERT(end.offsetInContainerNode() < position.offsetInContainerNode());
- end = Position(containerNode->previousSibling(), end.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+ end = Position(static_cast<Text*>(text->previousSibling()), end.offsetInContainerNode());
}
- if (m_endOfLastParagraph.anchorType() == Position::PositionIsOffsetInAnchor && containerNode.get() == m_endOfLastParagraph.containerNode()) {
- if (m_endOfLastParagraph.offsetInContainerNode() < position.offsetInContainerNode())
- m_endOfLastParagraph = Position(containerNode->previousSibling(), m_endOfLastParagraph.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
- else
- m_endOfLastParagraph = Position(containerNode, m_endOfLastParagraph.offsetInContainerNode() - 1, Position::PositionIsOffsetInAnchor);
+ if (text == m_endOfLastParagraph.containerNode()) {
+ if (m_endOfLastParagraph.offsetInContainerNode() < position.offsetInContainerNode()) {
+ // We can only fix endOfLastParagraph if the previous node was still text and hasn't been modified by script.
+ if (text->previousSibling()->isTextNode()
+ && static_cast<unsigned>(m_endOfLastParagraph.offsetInContainerNode()) <= static_cast<Text*>(text->previousSibling())->length())
+ m_endOfLastParagraph = Position(static_cast<Text*>(text->previousSibling()), m_endOfLastParagraph.offsetInContainerNode());
+ } else
+ m_endOfLastParagraph = Position(text.get(), m_endOfLastParagraph.offsetInContainerNode() - 1);
}
- return Position(containerNode.get(), position.offsetInContainerNode() - 1, Position::PositionIsOffsetInAnchor);
+ return Position(text.get(), position.offsetInContainerNode() - 1);
}
PassRefPtr<Element> ApplyBlockElementCommand::createBlockElement() const
Modified: trunk/Source/WebCore/editing/ApplyStyleCommand.cpp (89951 => 89952)
--- trunk/Source/WebCore/editing/ApplyStyleCommand.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/ApplyStyleCommand.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -1117,60 +1117,65 @@
void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position& end)
{
- ASSERT(start.anchorType() == Position::PositionIsOffsetInAnchor);
+ ASSERT(start.containerNode()->isTextNode());
Position newEnd;
if (end.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode())
- newEnd = Position(end.containerNode(), end.offsetInContainerNode() - start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+ newEnd = Position(end.containerText(), end.offsetInContainerNode() - start.offsetInContainerNode());
else
newEnd = end;
- Text* text = static_cast<Text*>(start.deprecatedNode());
+ RefPtr<Text> text = start.containerText();
splitTextNode(text, start.offsetInContainerNode());
- updateStartEnd(firstPositionInNode(start.deprecatedNode()), newEnd);
+ updateStartEnd(firstPositionInNode(text.get()), newEnd);
}
void ApplyStyleCommand::splitTextAtEnd(const Position& start, const Position& end)
{
- ASSERT(end.anchorType() == Position::PositionIsOffsetInAnchor);
+ ASSERT(end.containerNode()->isTextNode());
bool shouldUpdateStart = start.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode();
Text* text = static_cast<Text *>(end.deprecatedNode());
splitTextNode(text, end.offsetInContainerNode());
Node* prevNode = text->previousSibling();
- ASSERT(prevNode);
- Position newStart = shouldUpdateStart ? Position(prevNode, start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor) : start;
+ if (!prevNode || !prevNode->isTextNode())
+ return;
+
+ Position newStart = shouldUpdateStart ? Position(static_cast<Text*>(prevNode), start.offsetInContainerNode()) : start;
updateStartEnd(newStart, lastPositionInNode(prevNode));
}
void ApplyStyleCommand::splitTextElementAtStart(const Position& start, const Position& end)
{
- ASSERT(start.anchorType() == Position::PositionIsOffsetInAnchor);
+ ASSERT(start.containerNode()->isTextNode());
Position newEnd;
- if (end.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode())
- newEnd = Position(end.containerNode(), end.offsetInContainerNode() - start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+ if (start.containerNode() == end.containerNode())
+ newEnd = Position(end.containerText(), end.offsetInContainerNode() - start.offsetInContainerNode());
else
newEnd = end;
- Text* text = static_cast<Text*>(start.deprecatedNode());
- splitTextNodeContainingElement(text, start.deprecatedEditingOffset());
- updateStartEnd(Position(start.deprecatedNode()->parentNode(), start.deprecatedNode()->nodeIndex(), Position::PositionIsOffsetInAnchor), newEnd);
+ splitTextNodeContainingElement(start.containerText(), start.offsetInContainerNode());
+ updateStartEnd(positionBeforeNode(start.containerNode()), newEnd);
}
void ApplyStyleCommand::splitTextElementAtEnd(const Position& start, const Position& end)
{
- ASSERT(end.anchorType() == Position::PositionIsOffsetInAnchor);
+ ASSERT(end.containerNode()->isTextNode());
- bool shouldUpdateStart = start.anchorType() == Position::PositionIsOffsetInAnchor && start.containerNode() == end.containerNode();
- Text* text = static_cast<Text*>(end.deprecatedNode());
- splitTextNodeContainingElement(text, end.deprecatedEditingOffset());
+ bool shouldUpdateStart = start.containerNode() == end.containerNode();
+ splitTextNodeContainingElement(end.containerText(), end.offsetInContainerNode());
- Node* prevNode = text->parentNode()->previousSibling()->lastChild();
- ASSERT(prevNode);
- Position newStart = shouldUpdateStart ? Position(prevNode, start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor) : start;
- updateStartEnd(newStart, Position(prevNode->parentNode(), prevNode->nodeIndex() + 1, Position::PositionIsOffsetInAnchor));
+ Node* parentElement = end.containerNode()->parentNode();
+ if (!parentElement || !parentElement->previousSibling())
+ return;
+ Node* firstTextNode = parentElement->previousSibling()->lastChild();
+ if (!firstTextNode || !firstTextNode->isTextNode())
+ return;
+
+ Position newStart = shouldUpdateStart ? Position(static_cast<Text*>(firstTextNode), start.offsetInContainerNode()) : start;
+ updateStartEnd(newStart, positionAfterNode(firstTextNode));
}
bool ApplyStyleCommand::shouldSplitTextElement(Element* element, EditingStyle* style)
@@ -1480,9 +1485,9 @@
Text* childText = static_cast<Text *>(child);
Text* nextText = static_cast<Text *>(next);
if (start.anchorType() == Position::PositionIsOffsetInAnchor && next == start.containerNode())
- newStart = Position(childText, childText->length() + start.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+ newStart = Position(childText, childText->length() + start.offsetInContainerNode());
if (end.anchorType() == Position::PositionIsOffsetInAnchor && next == end.containerNode())
- newEnd = Position(childText, childText->length() + end.offsetInContainerNode(), Position::PositionIsOffsetInAnchor);
+ newEnd = Position(childText, childText->length() + end.offsetInContainerNode());
String textToMove = nextText->data();
insertTextIntoNode(childText, childText->length(), textToMove);
removeNode(next);
Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (89951 => 89952)
--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -320,7 +320,7 @@
if (start.containerNode() != end.containerNode() || !start.containerNode()->isTextNode() || isTabSpanTextNode(start.containerNode()))
return Position();
- RefPtr<Text> textNode = static_cast<Text*>(start.containerNode());
+ RefPtr<Text> textNode = start.containerText();
replaceTextInNode(textNode, start.offsetInContainerNode(), end.offsetInContainerNode() - start.offsetInContainerNode(), text);
return Position(textNode.release(), start.offsetInContainerNode() + text.length());
Modified: trunk/Source/WebCore/editing/Editor.cpp (89951 => 89952)
--- trunk/Source/WebCore/editing/Editor.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/Editor.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -266,7 +266,7 @@
return false;
if (range->collapsed(ec)) {
- VisiblePosition start(Position(startContainer, range->startOffset(ec), Position::PositionIsOffsetInAnchor), DOWNSTREAM);
+ VisiblePosition start(range->startPosition(), DOWNSTREAM);
VisiblePosition previous = start.previous();
// FIXME: We sometimes allow deletions at the start of editable roots, like when the caret is in an empty list item.
if (previous.isNull() || previous.deepEquivalent().deprecatedNode()->rootEditableElement() != startContainer->rootEditableElement())
Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (89951 => 89952)
--- trunk/Source/WebCore/editing/FrameSelection.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -1462,45 +1462,23 @@
bool FrameSelection::setSelectedRange(Range* range, EAffinity affinity, bool closeTyping)
{
- if (!range)
+ if (!range || !range->startContainer() || !range->endContainer())
return false;
+ ASSERT(range->startContainer()->document() == range->endContainer()->document());
- ExceptionCode ec = 0;
- Node* startContainer = range->startContainer(ec);
- if (ec)
- return false;
-
- Node* endContainer = range->endContainer(ec);
- if (ec)
- return false;
-
- ASSERT(startContainer);
- ASSERT(endContainer);
- ASSERT(startContainer->document() == endContainer->document());
-
m_frame->document()->updateLayoutIgnorePendingStylesheets();
// Non-collapsed ranges are not allowed to start at the end of a line that is wrapped,
// they start at the beginning of the next line instead
+ ExceptionCode ec = 0;
bool collapsed = range->collapsed(ec);
if (ec)
return false;
-
- int startOffset = range->startOffset(ec);
- if (ec)
- return false;
- int endOffset = range->endOffset(ec);
- if (ec)
- return false;
-
// FIXME: Can we provide extentAffinity?
- VisiblePosition visibleStart(Position(startContainer, startOffset, Position::PositionIsOffsetInAnchor), collapsed ? affinity : DOWNSTREAM);
- VisiblePosition visibleEnd(Position(endContainer, endOffset, Position::PositionIsOffsetInAnchor), SEL_DEFAULT_AFFINITY);
- SetSelectionOptions options = ClearTypingStyle;
- if (closeTyping)
- options |= CloseTyping;
- setSelection(VisibleSelection(visibleStart, visibleEnd), options);
+ VisiblePosition visibleStart(range->startPosition(), collapsed ? affinity : DOWNSTREAM);
+ VisiblePosition visibleEnd(range->endPosition(), SEL_DEFAULT_AFFINITY);
+ setSelection(VisibleSelection(visibleStart, visibleEnd), ClearTypingStyle | (closeTyping ? CloseTyping : 0));
return true;
}
Modified: trunk/Source/WebCore/editing/InsertTextCommand.cpp (89951 => 89952)
--- trunk/Source/WebCore/editing/InsertTextCommand.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/InsertTextCommand.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -157,7 +157,7 @@
ASSERT(startPosition.containerNode()->isTextNode());
if (placeholder.isNotNull())
removePlaceholderAt(placeholder);
- RefPtr<Text> textNode = static_cast<Text*>(startPosition.containerNode());
+ RefPtr<Text> textNode = startPosition.containerText();
const unsigned offset = startPosition.offsetInContainerNode();
insertTextIntoNode(textNode, offset, text);
Modified: trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp (89951 => 89952)
--- trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -939,7 +939,7 @@
// since insertAsListItems already does the right thing.
if (!m_matchStyle && !enclosingList(insertionPos.containerNode()) && isStyleSpan(fragment.firstChild())) {
if (insertionPos.containerNode()->isTextNode() && insertionPos.offsetInContainerNode() && !insertionPos.atLastEditingPositionForNode()) {
- splitTextNodeContainingElement(static_cast<Text*>(insertionPos.containerNode()), insertionPos.offsetInContainerNode());
+ splitTextNodeContainingElement(insertionPos.containerText(), insertionPos.offsetInContainerNode());
insertionPos = firstPositionInNode(insertionPos.containerNode());
}
Modified: trunk/Source/WebCore/editing/VisiblePosition.cpp (89951 => 89952)
--- trunk/Source/WebCore/editing/VisiblePosition.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/VisiblePosition.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -552,8 +552,8 @@
case Position::PositionIsOffsetInAnchor:
break;
}
- Text* textNode = static_cast<Text*>(pos.containerNode());
- unsigned offset = pos.anchorType() == Position::PositionIsOffsetInAnchor ? pos.offsetInContainerNode() : 0;
+ unsigned offset = static_cast<unsigned>(pos.offsetInContainerNode());
+ Text* textNode = pos.containerText();
unsigned length = textNode->length();
if (offset >= length)
return 0;
@@ -649,14 +649,12 @@
VisiblePosition startVisiblePosition(const Range *r, EAffinity affinity)
{
- int exception = 0;
- return VisiblePosition(Position(r->startContainer(exception), r->startOffset(exception), Position::PositionIsOffsetInAnchor), affinity);
+ return VisiblePosition(r->startPosition(), affinity);
}
VisiblePosition endVisiblePosition(const Range *r, EAffinity affinity)
{
- int exception = 0;
- return VisiblePosition(Position(r->endContainer(exception), r->endOffset(exception), Position::PositionIsOffsetInAnchor), affinity);
+ return VisiblePosition(r->endPosition(), affinity);
}
bool setStart(Range *r, const VisiblePosition &visiblePosition)
Modified: trunk/Source/WebCore/editing/htmlediting.cpp (89951 => 89952)
--- trunk/Source/WebCore/editing/htmlediting.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/htmlediting.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -402,8 +402,7 @@
static Node* firstInSpecialElement(const Position& pos)
{
- // FIXME: This begins at pos.deprecatedNode(), which doesn't necessarily contain pos (suppose pos was [img, 0]). See <rdar://problem/5027702>.
- Node* rootEditableElement = pos.deprecatedNode()->rootEditableElement();
+ Node* rootEditableElement = pos.containerNode()->rootEditableElement();
for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
if (isSpecialElement(n)) {
VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
@@ -418,12 +417,11 @@
static Node* lastInSpecialElement(const Position& pos)
{
- // FIXME: This begins at pos.deprecatedNode(), which doesn't necessarily contain pos (suppose pos was [img, 0]). See <rdar://problem/5027702>.
- Node* rootEditableElement = pos.deprecatedNode()->rootEditableElement();
+ Node* rootEditableElement = pos.containerNode()->rootEditableElement();
for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode())
if (isSpecialElement(n)) {
VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
- VisiblePosition lastInElement = VisiblePosition(Position(n, n->childNodeCount(), Position::PositionIsOffsetInAnchor), DOWNSTREAM);
+ VisiblePosition lastInElement = VisiblePosition(lastPositionInOrAfterNode(n), DOWNSTREAM);
if (isTableElement(n) && vPos == lastInElement.previous())
return n;
if (vPos == lastInElement)
Modified: trunk/Source/WebCore/editing/visible_units.cpp (89951 => 89952)
--- trunk/Source/WebCore/editing/visible_units.cpp 2011-06-28 20:04:05 UTC (rev 89951)
+++ trunk/Source/WebCore/editing/visible_units.cpp 2011-06-28 20:07:31 UTC (rev 89952)
@@ -437,12 +437,12 @@
Position pos;
if (endNode->hasTagName(brTag)) {
pos = positionBeforeNode(endNode);
- } else if (endBox->isInlineTextBox()) {
- InlineTextBox *endTextBox = static_cast<InlineTextBox *>(endBox);
+ } else if (endBox->isInlineTextBox() && endNode->isTextNode()) {
+ InlineTextBox* endTextBox = static_cast<InlineTextBox *>(endBox);
int endOffset = endTextBox->start();
if (!endTextBox->isLineBreak())
endOffset += endTextBox->len();
- pos = Position(endNode, endOffset, Position::PositionIsOffsetInAnchor);
+ pos = Position(static_cast<Text*>(endNode), endOffset);
} else
pos = positionAfterNode(endNode);
@@ -793,6 +793,7 @@
break;
if (r->isText() && r->caretMaxRenderedOffset() > 0) {
+ ASSERT(n->isTextNode());
type = Position::PositionIsOffsetInAnchor;
if (style->preserveNewline()) {
const UChar* chars = toRenderText(r)->characters();
@@ -800,9 +801,10 @@
int o = offset;
if (n == startNode && o < i)
i = max(0, o);
- while (--i >= 0)
+ while (--i >= 0) {
if (chars[i] == '\n')
- return VisiblePosition(Position(n, i + 1, Position::PositionIsOffsetInAnchor), DOWNSTREAM);
+ return VisiblePosition(Position(static_cast<Text*>(n), i + 1), DOWNSTREAM);
+ }
}
node = n;
offset = 0;
@@ -815,9 +817,11 @@
n = n->traversePreviousNodePostOrder(startBlock);
}
- if (type == Position::PositionIsOffsetInAnchor)
+ if (type == Position::PositionIsOffsetInAnchor) {
+ ASSERT(type != Position::PositionIsOffsetInAnchor || !offset);
return VisiblePosition(Position(node, offset, type), DOWNSTREAM);
-
+ }
+
return VisiblePosition(Position(node, type), DOWNSTREAM);
}
@@ -867,14 +871,16 @@
// FIXME: We avoid returning a position where the renderer can't accept the caret.
if (r->isText() && r->caretMaxRenderedOffset() > 0) {
+ ASSERT(n->isTextNode());
int length = toRenderText(r)->textLength();
type = Position::PositionIsOffsetInAnchor;
if (style->preserveNewline()) {
const UChar* chars = toRenderText(r)->characters();
int o = n == startNode ? offset : 0;
- for (int i = o; i < length; ++i)
+ for (int i = o; i < length; ++i) {
if (chars[i] == '\n')
- return VisiblePosition(Position(n, i, Position::PositionIsOffsetInAnchor), DOWNSTREAM);
+ return VisiblePosition(Position(static_cast<Text*>(n), i), DOWNSTREAM);
+ }
}
node = n;
offset = r->caretMaxOffset();