Commit 50d7db0a authored by eric@webkit.org's avatar eric@webkit.org

Reviewed by Justin Garcia.

        DOMSelection.getRangeAt() returns a different range than the selection
        https://bugs.webkit.org/show_bug.cgi?id=23601

        Rename toRange to toNormalizedRange and add new firstRange which returns an unmodified range

        Test: fast/dom/Selection/getRangeAt.html

        * WebCore.base.exp:
        * dom/InputElement.cpp:
        (WebCore::InputElement::handleBeforeTextInsertedEvent):
        * editing/DeleteButtonController.cpp:
        (WebCore::enclosingDeletableElement):
        * editing/Editor.cpp:
        (WebCore::Editor::selectedRange):
        (WebCore::Editor::fontForSelection):
        (WebCore::Editor::applyStyleToSelection):
        (WebCore::Editor::applyParagraphStyleToSelection):
        (WebCore::Editor::insertTextWithoutSendingTextEvent):
        (WebCore::Editor::insertLineBreak):
        (WebCore::Editor::insertParagraphSeparator):
        (WebCore::Editor::ignoreSpelling):
        (WebCore::Editor::isSelectionUngrammatical):
        (WebCore::Editor::guessesForUngrammaticalSelection):
        (WebCore::markMisspellingsOrBadGrammar):
        (WebCore::Editor::rangeForPoint):
        * editing/EditorCommand.cpp:
        (WebCore::expandSelectionToGranularity):
        (WebCore::executeDeleteToMark):
        (WebCore::executeSelectToMark):
        * editing/RemoveFormatCommand.cpp:
        (WebCore::RemoveFormatCommand::doApply):
        * editing/ReplaceSelectionCommand.cpp:
        (WebCore::ReplacementFragment::ReplacementFragment):
        * editing/Selection.cpp:
        (WebCore::Selection::firstRange):
        (WebCore::Selection::toNormalizedRange):
        * editing/Selection.h:
        * editing/SelectionController.h:
        (WebCore::SelectionController::toNormalizedRange):
        * editing/TypingCommand.cpp:
        (WebCore::TypingCommand::deleteKeyPressed):
        (WebCore::TypingCommand::forwardDeleteKeyPressed):
        * editing/markup.cpp:
        (WebCore::createMarkup):
        * loader/archive/cf/LegacyWebArchive.cpp:
        (WebCore::LegacyWebArchive::createFromSelection):
        * page/AccessibilityRenderObject.cpp:
        (WebCore::AccessibilityRenderObject::ariaSelectedTextDOMRange):
        * page/ContextMenuController.cpp:
        (WebCore::ContextMenuController::contextMenuItemSelected):
        * page/DOMSelection.cpp:
        (WebCore::DOMSelection::getRangeAt):
        (WebCore::DOMSelection::addRange):
        (WebCore::DOMSelection::deleteFromDocument):
        (WebCore::DOMSelection::containsNode):
        (WebCore::DOMSelection::toString):
        * page/DragController.cpp:
        (WebCore::setSelectionToDragCaret):
        (WebCore::DragController::concludeEditDrag):
        (WebCore::DragController::startDrag):
        * page/EventHandler.cpp:
        (WebCore::EventHandler::dispatchMouseEvent):
        * page/Frame.cpp:
        (WebCore::Frame::selectedText):
        (WebCore::Frame::shouldChangeSelection):
        (WebCore::Frame::shouldDeleteSelection):
        (WebCore::Frame::selectionComputedStyle):
        (WebCore::Frame::selectionTextRects):
        (WebCore::Frame::findString):
        (WebCore::Frame::respondToChangedSelection):
        * platform/ContextMenu.cpp:
        (WebCore::selectionContainsPossibleWord):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@40746 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 1fbfab92
2009-02-05 Eric Seidel <eric@webkit.org>
Reviewed by Eric Seidel.
DOMSelection.getRangeAt() returns a different range than the selection
https://bugs.webkit.org/show_bug.cgi?id=23601
Rename toRange to toNormalizedRange and add new firstRange which returns an unmodified range
* fast/dom/Selection/getRangeAt.html: Added.
* fast/dom/Selection/resources/TEMPLATE.html: Copied from LayoutTests/fast/dom/CSSStyleDeclaration/resources/TEMPLATE.html.
* fast/dom/Selection/resources/getRangeAt.js: Added.
2009-02-06 Justin Garcia <justin.garcia@apple.com>
Reviewed by Oliver Hunt.
......
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<link rel="stylesheet" href="../../js/resources/js-test-style.css">
<script src="../../js/resources/js-test-pre.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script src="resources/getRangeAt.js"></script>
<script src="../../js/resources/js-test-post.js"></script>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<link rel="stylesheet" href="../../js/resources/js-test-style.css">
<script src="../../js/resources/js-test-pre.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script src="YOUR_JS_FILE_HERE"></script>
<script src="../../js/resources/js-test-post.js"></script>
</body>
</html>
description("Test to make sure that getRangeAt does not modify the range when returning it.")
var div = document.createElement('div');
document.body.appendChild(div);
var textNode = document.createTextNode("asd");
div.appendChild(textNode);
var sel = window.getSelection();
sel.collapse(textNode, 0);
var range = sel.getRangeAt(0);
var result = range.comparePoint(textNode, 0);
if (result == 0) {
testPassed("range is correctly (text, 0)");
} else {
testFailed("range did not match (text, 0)");
debug("window.getSelection():");
debug("anchorNode: " + sel.anchorNode);
debug("anchorOffset: " + sel.anchorOffset);
debug("focusNode: " + sel.focusNode);
debug("focusOffset: " + sel.focusOffset);
debug("window.getSelection().getRangeAt(0):");
debug("startContainer: " + range.startContainer);
debug("startOffset: " + range.startOffset);
debug("endContainer: " + range.endContainer);
debug("endOffset: " + range.endOffset);
}
// Clean up after ourselves
document.body.removeChild(div);
var successfullyParsed = true;
2009-02-06 Eric Seidel <eric@webkit.org>
Reviewed by Justin Garcia.
DOMSelection.getRangeAt() returns a different range than the selection
https://bugs.webkit.org/show_bug.cgi?id=23601
Rename toRange to toNormalizedRange and add new firstRange which returns an unmodified range
Test: fast/dom/Selection/getRangeAt.html
* WebCore.base.exp:
* dom/InputElement.cpp:
(WebCore::InputElement::handleBeforeTextInsertedEvent):
* editing/DeleteButtonController.cpp:
(WebCore::enclosingDeletableElement):
* editing/Editor.cpp:
(WebCore::Editor::selectedRange):
(WebCore::Editor::fontForSelection):
(WebCore::Editor::applyStyleToSelection):
(WebCore::Editor::applyParagraphStyleToSelection):
(WebCore::Editor::insertTextWithoutSendingTextEvent):
(WebCore::Editor::insertLineBreak):
(WebCore::Editor::insertParagraphSeparator):
(WebCore::Editor::ignoreSpelling):
(WebCore::Editor::isSelectionUngrammatical):
(WebCore::Editor::guessesForUngrammaticalSelection):
(WebCore::markMisspellingsOrBadGrammar):
(WebCore::Editor::rangeForPoint):
* editing/EditorCommand.cpp:
(WebCore::expandSelectionToGranularity):
(WebCore::executeDeleteToMark):
(WebCore::executeSelectToMark):
* editing/RemoveFormatCommand.cpp:
(WebCore::RemoveFormatCommand::doApply):
* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplacementFragment::ReplacementFragment):
* editing/Selection.cpp:
(WebCore::Selection::firstRange):
(WebCore::Selection::toNormalizedRange):
* editing/Selection.h:
* editing/SelectionController.h:
(WebCore::SelectionController::toNormalizedRange):
* editing/TypingCommand.cpp:
(WebCore::TypingCommand::deleteKeyPressed):
(WebCore::TypingCommand::forwardDeleteKeyPressed):
* editing/markup.cpp:
(WebCore::createMarkup):
* loader/archive/cf/LegacyWebArchive.cpp:
(WebCore::LegacyWebArchive::createFromSelection):
* page/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::ariaSelectedTextDOMRange):
* page/ContextMenuController.cpp:
(WebCore::ContextMenuController::contextMenuItemSelected):
* page/DOMSelection.cpp:
(WebCore::DOMSelection::getRangeAt):
(WebCore::DOMSelection::addRange):
(WebCore::DOMSelection::deleteFromDocument):
(WebCore::DOMSelection::containsNode):
(WebCore::DOMSelection::toString):
* page/DragController.cpp:
(WebCore::setSelectionToDragCaret):
(WebCore::DragController::concludeEditDrag):
(WebCore::DragController::startDrag):
* page/EventHandler.cpp:
(WebCore::EventHandler::dispatchMouseEvent):
* page/Frame.cpp:
(WebCore::Frame::selectedText):
(WebCore::Frame::shouldChangeSelection):
(WebCore::Frame::shouldDeleteSelection):
(WebCore::Frame::selectionComputedStyle):
(WebCore::Frame::selectionTextRects):
(WebCore::Frame::findString):
(WebCore::Frame::respondToChangedSelection):
* platform/ContextMenu.cpp:
(WebCore::selectionContainsPossibleWord):
2009-02-06 Brady Eidson <beidson@apple.com>
Reviewed by Dan Bernstein
......@@ -901,9 +901,9 @@ __ZNK7WebCore9FrameTree5childERKNS_12AtomicStringE
__ZNK7WebCore9FrameTree6parentEb
__ZNK7WebCore9FrameView11needsLayoutEv
__ZNK7WebCore9Selection17isContentEditableEv
__ZNK7WebCore9Selection17toNormalizedRangeEv
__ZNK7WebCore9Selection19rootEditableElementEv
__ZNK7WebCore9Selection23isContentRichlyEditableEv
__ZNK7WebCore9Selection7toRangeEv
__ZNK7WebCore9TimerBase8isActiveEv
__ZTVN7WebCore12ChromeClientE
__ZTVN7WebCore17FileChooserClientE
......
......@@ -218,7 +218,7 @@ void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, Documen
// Make sure that the text to be inserted will not violate the maxLength.
int oldLength = numGraphemeClusters(data.inputElement()->value().impl());
ASSERT(oldLength <= data.maxLength());
int selectionLength = numGraphemeClusters(plainText(document->frame()->selection()->selection().toRange().get()).impl());
int selectionLength = numGraphemeClusters(plainText(document->frame()->selection()->selection().toNormalizedRange().get()).impl());
ASSERT(oldLength >= selectionLength);
int maxNewLength = data.maxLength() - (oldLength - selectionLength);
......
......@@ -106,7 +106,7 @@ static HTMLElement* enclosingDeletableElement(const Selection& selection)
if (!selection.isContentEditable())
return 0;
RefPtr<Range> range = selection.toRange();
RefPtr<Range> range = selection.toNormalizedRange();
if (!range)
return 0;
......
......@@ -317,7 +317,7 @@ PassRefPtr<Range> Editor::selectedRange()
{
if (!m_frame)
return 0;
return m_frame->selection()->toRange();
return m_frame->selection()->toNormalizedRange();
}
bool Editor::shouldDeleteRange(Range* range) const
......@@ -419,7 +419,7 @@ const SimpleFontData* Editor::fontForSelection(bool& hasMultipleFonts) const
const SimpleFontData* font = 0;
RefPtr<Range> range = m_frame->selection()->toRange();
RefPtr<Range> range = m_frame->selection()->toNormalizedRange();
Node* startNode = range->editingStartPosition().node();
if (startNode) {
Node* pastEnd = range->pastLastNode();
......@@ -748,7 +748,7 @@ void Editor::applyStyleToSelection(CSSStyleDeclaration* style, EditAction editin
if (!style || style->length() == 0 || !canEditRichly())
return;
if (client() && client()->shouldApplyStyle(style, m_frame->selection()->toRange().get()))
if (client() && client()->shouldApplyStyle(style, m_frame->selection()->toNormalizedRange().get()))
applyStyle(style, editingAction);
}
......@@ -757,7 +757,7 @@ void Editor::applyParagraphStyleToSelection(CSSStyleDeclaration* style, EditActi
if (!style || style->length() == 0 || !canEditRichly())
return;
if (client() && client()->shouldApplyStyle(style, m_frame->selection()->toRange().get()))
if (client() && client()->shouldApplyStyle(style, m_frame->selection()->toNormalizedRange().get()))
applyParagraphStyle(style, editingAction);
}
......@@ -965,7 +965,7 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
Selection selection = selectionForCommand(triggeringEvent);
if (!selection.isContentEditable())
return false;
RefPtr<Range> range = selection.toRange();
RefPtr<Range> range = selection.toNormalizedRange();
if (!shouldInsertText(text, range.get(), EditorInsertActionTyped))
return true;
......@@ -996,7 +996,7 @@ bool Editor::insertLineBreak()
if (!canEdit())
return false;
if (!shouldInsertText("\n", m_frame->selection()->toRange().get(), EditorInsertActionTyped))
if (!shouldInsertText("\n", m_frame->selection()->toNormalizedRange().get(), EditorInsertActionTyped))
return true;
TypingCommand::insertLineBreak(m_frame->document());
......@@ -1012,7 +1012,7 @@ bool Editor::insertParagraphSeparator()
if (!canEditRichly())
return insertLineBreak();
if (!shouldInsertText("\n", m_frame->selection()->toRange().get(), EditorInsertActionTyped))
if (!shouldInsertText("\n", m_frame->selection()->toNormalizedRange().get(), EditorInsertActionTyped))
return true;
TypingCommand::insertParagraphSeparator(m_frame->document());
......@@ -1337,7 +1337,7 @@ void Editor::ignoreSpelling()
if (!client())
return;
RefPtr<Range> selectedRange = frame()->selection()->toRange();
RefPtr<Range> selectedRange = frame()->selection()->toNormalizedRange();
if (selectedRange)
frame()->document()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
......@@ -1773,7 +1773,7 @@ bool Editor::isSelectionUngrammatical()
return false;
#else
Vector<String> ignoredGuesses;
return isRangeUngrammatical(client(), frame()->selection()->toRange().get(), ignoredGuesses);
return isRangeUngrammatical(client(), frame()->selection()->toNormalizedRange().get(), ignoredGuesses);
#endif
}
......@@ -1784,7 +1784,7 @@ Vector<String> Editor::guessesForUngrammaticalSelection()
#else
Vector<String> guesses;
// Ignore the result of isRangeUngrammatical; we just want the guesses, whether or not there are any
isRangeUngrammatical(client(), frame()->selection()->toRange().get(), guesses);
isRangeUngrammatical(client(), frame()->selection()->toNormalizedRange().get(), guesses);
return guesses;
#endif
}
......@@ -1871,7 +1871,7 @@ static void markMisspellingsOrBadGrammar(Editor* editor, const Selection& select
if (!editor->isContinuousSpellCheckingEnabled())
return;
RefPtr<Range> searchRange(selection.toRange());
RefPtr<Range> searchRange(selection.toNormalizedRange());
if (!searchRange)
return;
......@@ -1923,7 +1923,7 @@ PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint)
return 0;
IntPoint framePoint = frameView->windowToContents(windowPoint);
Selection selection(frame->visiblePositionForPoint(framePoint));
return avoidIntersectionWithNode(selection.toRange().get(), deleteButtonController() ? deleteButtonController()->containerElement() : 0);
return avoidIntersectionWithNode(selection.toNormalizedRange().get(), deleteButtonController() ? deleteButtonController()->containerElement() : 0);
}
void Editor::revealSelectionAfterEditingOperation()
......
......@@ -186,13 +186,13 @@ static bool expandSelectionToGranularity(Frame* frame, TextGranularity granulari
{
Selection selection = frame->selection()->selection();
selection.expandUsingGranularity(granularity);
RefPtr<Range> newRange = selection.toRange();
RefPtr<Range> newRange = selection.toNormalizedRange();
if (!newRange)
return false;
ExceptionCode ec = 0;
if (newRange->collapsed(ec))
return false;
RefPtr<Range> oldRange = frame->selection()->selection().toRange();
RefPtr<Range> oldRange = frame->selection()->selection().toNormalizedRange();
EAffinity affinity = frame->selection()->affinity();
if (!frame->editor()->client()->shouldChangeSelectedRange(oldRange.get(), newRange.get(), affinity, false))
return false;
......@@ -342,7 +342,7 @@ static bool executeDeleteToEndOfParagraph(Frame* frame, Event*, EditorCommandSou
static bool executeDeleteToMark(Frame* frame, Event*, EditorCommandSource, const String&)
{
RefPtr<Range> mark = frame->mark().toRange();
RefPtr<Range> mark = frame->mark().toNormalizedRange();
if (mark) {
SelectionController* selection = frame->selection();
bool selected = selection->setSelectedRange(unionDOMRanges(mark.get(), frame->editor()->selectedRange().get()).get(), DOWNSTREAM, true);
......@@ -888,7 +888,7 @@ static bool executeSelectSentence(Frame* frame, Event*, EditorCommandSource, con
static bool executeSelectToMark(Frame* frame, Event*, EditorCommandSource, const String&)
{
RefPtr<Range> mark = frame->mark().toRange();
RefPtr<Range> mark = frame->mark().toNormalizedRange();
RefPtr<Range> selection = frame->editor()->selectedRange();
if (!mark || !selection) {
systemBeep();
......
......@@ -49,7 +49,7 @@ void RemoveFormatCommand::doApply()
Frame* frame = document()->frame();
// Make a plain text string from the selection to remove formatting like tables and lists.
String string = plainText(frame->selection()->selection().toRange().get());
String string = plainText(frame->selection()->selection().toNormalizedRange().get());
// Get the default style for this editable root, it's the style that we'll give the
// content that we're operating on.
......
......@@ -136,7 +136,7 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
Node* styleNode = selection.base().node();
RefPtr<Node> holder = insertFragmentForTestRendering(styleNode);
RefPtr<Range> range = Selection::selectionFromContentsOfNode(holder.get()).toRange();
RefPtr<Range> range = Selection::selectionFromContentsOfNode(holder.get()).toNormalizedRange();
String text = plainText(range.get());
// Give the root a chance to change the text.
RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text);
......@@ -147,7 +147,7 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
restoreTestRenderingNodesToFragment(holder.get());
removeNode(holder);
m_fragment = createFragmentFromText(selection.toRange().get(), evt->text());
m_fragment = createFragmentFromText(selection.toNormalizedRange().get(), evt->text());
if (!m_fragment->firstChild())
return;
holder = insertFragmentForTestRendering(styleNode);
......
......@@ -122,7 +122,16 @@ void Selection::setExtent(const VisiblePosition& visiblePosition)
validate();
}
PassRefPtr<Range> Selection::toRange() const
PassRefPtr<Range> Selection::firstRange() const
{
if (isNone())
return 0;
Position start = rangeCompliantEquivalent(m_start);
Position end = rangeCompliantEquivalent(m_end);
return Range::create(start.node()->document(), start, end);
}
PassRefPtr<Range> Selection::toNormalizedRange() const
{
if (isNone())
return 0;
......@@ -170,19 +179,9 @@ PassRefPtr<Range> Selection::toRange() const
e = rangeCompliantEquivalent(e);
}
ExceptionCode ec = 0;
RefPtr<Range> result(Range::create(s.node()->document()));
result->setStart(s.node(), s.offset(), ec);
if (ec) {
LOG_ERROR("Exception setting Range start from Selection: %d", ec);
return 0;
}
result->setEnd(e.node(), e.offset(), ec);
if (ec) {
LOG_ERROR("Exception setting Range end from Selection: %d", ec);
return 0;
}
return result.release();
// Selections are supposed to always be valid. This constructor will ASSERT
// if a valid range could not be created, which is fine for this callsite.
return Range::create(s.node()->document(), s, e);
}
bool Selection::expandUsingGranularity(TextGranularity granularity)
......
......@@ -81,7 +81,13 @@ public:
bool expandUsingGranularity(TextGranularity granularity);
TextGranularity granularity() const { return m_granularity; }
PassRefPtr<Range> toRange() const;
// We don't yet support multi-range selections, so we only ever have one range to return.
PassRefPtr<Range> firstRange() const;
// FIXME: Most callers probably don't want this function, but are using it
// for historical reasons. toNormalizedRange contracts the range around
// text, and moves the caret upstream before returning the range.
PassRefPtr<Range> toNormalizedRange() const;
Element* rootEditableElement() const;
bool isContentEditable() const;
......
......@@ -103,7 +103,7 @@ public:
bool isCaretOrRange() const { return m_sel.isCaretOrRange(); }
bool isInPasswordField() const;
PassRefPtr<Range> toRange() const { return m_sel.toRange(); }
PassRefPtr<Range> toNormalizedRange() const { return m_sel.toNormalizedRange(); }
void debugRenderer(RenderObject*, bool selected) const;
......
......@@ -438,7 +438,7 @@ void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
if (selectionToDelete.isCaretOrRange() && document()->frame()->shouldDeleteSelection(selectionToDelete)) {
if (killRing)
document()->frame()->editor()->addToKillRing(selectionToDelete.toRange().get(), false);
document()->frame()->editor()->addToKillRing(selectionToDelete.toNormalizedRange().get(), false);
// Make undo select everything that has been deleted, unless an undo will undo more than just this deletion.
// FIXME: This behaves like TextEdit except for the case where you open with text insertion and then delete
// more text than you insert. In that case all of the text that was around originally should be selected.
......@@ -516,7 +516,7 @@ void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool ki
if (selectionToDelete.isCaretOrRange() && document()->frame()->shouldDeleteSelection(selectionToDelete)) {
if (killRing)
document()->frame()->editor()->addToKillRing(selectionToDelete.toRange().get(), false);
document()->frame()->editor()->addToKillRing(selectionToDelete.toNormalizedRange().get(), false);
// make undo select what was deleted
setStartingSelection(selectionAfterUndo);
CompositeEditCommand::deleteSelection(selectionToDelete, m_smartDelete);
......
......@@ -309,27 +309,32 @@ Node* enclosingBlock(Node* node)
return static_cast<Element*>(enclosingNodeOfType(Position(node, 0), isBlock));
}
// Internally editing uses "invalid" positions for historical reasons. For
// example, in <div><img /></div>, Editing might use (img, 1) for the position
// after <img>, but we have to convert that to (div, 1) before handing the
// position to a Range object. Ideally all internal positions should
// be "range compliant" for simplicity.
Position rangeCompliantEquivalent(const Position& pos)
{
if (pos.isNull())
return Position();
Node *node = pos.node();
Node* node = pos.node();
if (pos.offset() <= 0) {
if (node->parentNode() && (editingIgnoresContent(node) || isTableElement(node)))
return positionBeforeNode(node);
return Position(node, 0);
}
if (node->offsetInCharacters())
return Position(node, min(node->maxCharacterOffset(), pos.offset()));
int maxCompliantOffset = node->childNodeCount();
if (pos.offset() > maxCompliantOffset) {
if (node->parentNode())
return positionAfterNode(node);
// there is no other option at this point than to
// use the highest allowed position in the node
return Position(node, maxCompliantOffset);
......
......@@ -901,7 +901,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
// FIXME: Only include markup for a fully selected root (and ancestors of lastClosed up to that root) if
// there are styles/attributes on those nodes that need to be included to preserve the appearance of the copied markup.
// FIXME: Do this for all fully selected blocks, not just the body.
Node* fullySelectedRoot = body && *Selection::selectionFromContentsOfNode(body).toRange() == *updatedRange ? body : 0;
Node* fullySelectedRoot = body && *Selection::selectionFromContentsOfNode(body).toNormalizedRange() == *updatedRange ? body : 0;
if (annotate && fullySelectedRoot)
specialCommonAncestor = fullySelectedRoot;
......
......@@ -568,7 +568,7 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::createFromSelection(Frame* frame)
if (!frame)
return 0;
RefPtr<Range> selectionRange = frame->selection()->toRange();
RefPtr<Range> selectionRange = frame->selection()->toNormalizedRange();
Vector<Node*> nodeList;
String markupString = frame->documentTypeString() + createMarkup(selectionRange.get(), &nodeList, AnnotateForInterchange);
......
......@@ -1272,7 +1272,7 @@ PassRefPtr<Range> AccessibilityRenderObject::ariaSelectedTextDOMRange() const
if (!node)
return 0;
RefPtr<Range> currentSelectionRange = selection().toRange();
RefPtr<Range> currentSelectionRange = selection().toNormalizedRange();
if (!currentSelectionRange)
return 0;
......
......@@ -193,7 +193,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
#endif
case ContextMenuItemTagSpellingGuess:
ASSERT(frame->selectedText().length());
if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toRange().get(),
if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toNormalizedRange().get(),
EditorInsertActionPasted)) {
Document* document = frame->document();
RefPtr<ReplaceSelectionCommand> command =
......@@ -238,7 +238,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
break;
case ContextMenuItemTagStartSpeaking: {
ExceptionCode ec;
RefPtr<Range> selectedRange = frame->selection()->toRange();
RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
if (!selectedRange || selectedRange->collapsed(ec)) {
Document* document = result.innerNonSharedNode()->document();
selectedRange = document->createRange();
......
......@@ -298,8 +298,11 @@ PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec)
return 0;
}
// If you're hitting this, you've added broken multi-range selection support
ASSERT(rangeCount() == 1);
const Selection& selection = m_frame->selection()->selection();
return selection.toRange();
return selection.firstRange();
}
void DOMSelection::removeAllRanges()
......@@ -323,7 +326,7 @@ void DOMSelection::addRange(Range* r)
return;
}
RefPtr<Range> range = selection->selection().toRange();
RefPtr<Range> range = selection->selection().toNormalizedRange();
ExceptionCode ec = 0;
if (r->compareBoundaryPoints(Range::START_TO_START, range.get(), ec) == -1) {
// We don't support discontiguous selection. We don't do anything if r and range don't intersect.
......@@ -361,7 +364,7 @@ void DOMSelection::deleteFromDocument()
if (isCollapsed())
selection->modify(SelectionController::EXTEND, SelectionController::BACKWARD, CharacterGranularity);
RefPtr<Range> selectedRange = selection->selection().toRange();
RefPtr<Range> selectedRange = selection->selection().toNormalizedRange();
ExceptionCode ec = 0;
selectedRange->deleteContents(ec);
......@@ -383,7 +386,7 @@ bool DOMSelection::containsNode(const Node* n, bool allowPartial) const
Node* parentNode = n->parentNode();
unsigned nodeIndex = n->nodeIndex();
RefPtr<Range> selectedRange = selection->selection().toRange();
RefPtr<Range> selectedRange = selection->selection().toNormalizedRange();
if (!parentNode)
return false;
......@@ -418,7 +421,7 @@ String DOMSelection::toString()
if (!m_frame)
return String();
return plainText(m_frame->selection()->selection().toRange().get());
return plainText(m_frame->selection()->selection().toNormalizedRange().get());
}
} // namespace WebCore
......@@ -315,7 +315,7 @@ static bool setSelectionToDragCaret(Frame* frame, Selection& dragCaret, RefPtr<R
if (frame->selection()->isNone()) {
dragCaret = frame->visiblePositionForPoint(point);
frame->selection()->setSelection(dragCaret);
range = dragCaret.toRange();
range = dragCaret.toNormalizedRange();
}
return !frame->selection()->isNone() && frame->selection()->isContentEditable();
}
......@@ -340,7 +340,7 @@ bool DragController::concludeEditDrag(DragData* dragData)
return false;
if (!innerFrame)
return false;
RefPtr<Range> innerRange = innerFrame->selection()->toRange();
RefPtr<Range> innerRange = innerFrame->selection()->toNormalizedRange();
RefPtr<CSSStyleDeclaration> style = m_document->createCSSStyleDeclaration();
ExceptionCode ec;
style->setProperty("color", color.name(), ec);
......@@ -383,7 +383,7 @@ bool DragController::concludeEditDrag(DragData* dragData)
Selection dragCaret(m_page->dragCaretController()->selection());
m_page->dragCaretController()->clear();
RefPtr<Range> range = dragCaret.toRange();
RefPtr<Range> range = dragCaret.toNormalizedRange();
// For range to be null a WebKit client must have done something bad while
// manually controlling drag behaviour
......@@ -673,7 +673,7 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
}
doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true);
} else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) {
RefPtr<Range> selectionRange = src->selection()->toRange();
RefPtr<Range> selectionRange = src->selection()->toNormalizedRange();
ASSERT(selectionRange);
if (!clipboard->hasData())
clipboard->writeRange(selectionRange.get(), src);
......
......@@ -1572,7 +1572,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
ExceptionCode ec = 0;
Node* n = node->isShadowNode() ? node->shadowParentNode() : node;
if (m_frame->selection()->isRange() &&
m_frame->selection()->toRange()->compareNode(n, ec) == Range::NODE_INSIDE &&
m_frame->selection()->toNormalizedRange()->compareNode(n, ec) == Range::NODE_INSIDE &&
n->isDescendantOf(m_frame->document()->focusedNode()))
return false;
......
......@@ -275,7 +275,7 @@ Settings* Frame::settings() const
String Frame::selectedText() const
{
return plainText(selection()->toRange().get());
return plainText(selection()->toNormalizedRange().get());
}
IntRect Frame::firstRectForRange(Range* range) const
......@@ -834,13 +834,13 @@ bool Frame::shouldChangeSelection(const Selection& newSelection) const
bool Frame::shouldChangeSelection(const Selection& oldSelection, const Selection& newSelection, EAffinity affinity, bool stillSelecting) const
{
return editor()->client()->shouldChangeSelectedRange(oldSelection.toRange().get(), newSelection.toRange().get(),
return editor()->client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(),
affinity, stillSelecting);
}
bool Frame::shouldDeleteSelection(const Selection& selection) const
{
return editor()->client()->shouldDeleteRange(selection.toRange().get());
return editor()->client()->shouldDeleteRange(selection.toNormalizedRange().get());
}
bool Frame::isContentEditable() const
......@@ -952,7 +952,7 @@ PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nod
if (selection()->isNone())
return 0;
RefPtr<Range> range(selection()->toRange());
RefPtr<Range> range(selection()->toNormalizedRange());
Position pos = range->editingStartPosition();
Element *elem = pos.element();
......@@ -1196,7 +1196,7 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte
if (!root)
return;
RefPtr<Range> selectedRange = selection()->toRange();