[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

darin at apple.com darin at apple.com
Wed Dec 22 13:18:41 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit b17ec2f7de4b7e27735af9a8c57133b05bac9035
Author: darin at apple.com <darin at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Sep 10 22:06:47 2010 +0000

    2010-09-09  Darin Adler  <darin at apple.com>
    
            Reviewed by Adam Barth.
    
            Move functions from Frame to SelectionController as planned
            https://bugs.webkit.org/show_bug.cgi?id=45508
    
            * src/WebFrameImpl.cpp:
            (WebKit::WebFrameImpl::selectionBoundsRect):
            Call functions on selection().
    2010-09-09  Darin Adler  <darin at apple.com>
    
            Reviewed by Adam Barth.
    
            Move functions from Frame to SelectionController as planned
            https://bugs.webkit.org/show_bug.cgi?id=45508
    
            * WebView.cpp:
            (WebView::selectionRect):
            (WebView::centerSelectionInVisibleArea):
            Call functions on selection().
    2010-09-09  Darin Adler  <darin at apple.com>
    
            Reviewed by Adam Barth.
    
            Move functions from Frame to SelectionController as planned
            https://bugs.webkit.org/show_bug.cgi?id=45508
    
            * WebView/WebFrame.mm:
            (-[WebFrame _selectionGranularity]):
            (-[WebFrame _insertParagraphSeparatorInQuotedContent]):
            (-[WebFrame _typingStyle]):
            (-[WebFrame _replaceSelectionWithFragment:selectReplacement:smartReplace:matchStyle:]):
            * WebView/WebHTMLRepresentation.mm:
            (-[WebHTMLRepresentation currentForm]):
            * WebView/WebHTMLView.mm:
            (-[WebHTMLView jumpToSelection:]):
            (-[WebHTMLView centerSelectionInVisibleArea:]):
            (-[WebHTMLView _canSmartCopyOrDelete]):
            (-[WebHTMLView _lookUpInDictionaryFromMenu:]):
            (-[WebHTMLView selectionRect]):
            (-[WebHTMLView selectionTextRects]):
            (-[WebHTMLView selectionImageRect]):
            * WebView/WebView.mm:
            (-[WebView setEditable:]):
            Call functions on selection().
    2010-09-09  Darin Adler  <darin at apple.com>
    
            Reviewed by Adam Barth.
    
            Move functions from Frame to SelectionController as planned
            https://bugs.webkit.org/show_bug.cgi?id=45508
    
            Also removed Frame::dragCaretController since it just called Page::dragCaretController.
    
            * editing/SelectionController.cpp:
            (WebCore::SelectionController::setSelection):
            (WebCore::SelectionController::modify):
            (WebCore::SelectionController::selectFrameElementInParentIfFullySelected):
            (WebCore::SelectionController::selectAll):
            (WebCore::SelectionController::focusedOrActiveStateChanged):
            (WebCore::SelectionController::notifyRendererOfSelectionChange):
            (WebCore::isFrameElement):
            (WebCore::SelectionController::setFocusedNodeIfNeeded):
            (WebCore::SelectionController::paintDragCaret):
            (WebCore::SelectionController::shouldDeleteSelection):
            (WebCore::SelectionController::selectionBounds):
            (WebCore::SelectionController::selectionTextRects):
            (WebCore::scanForForm):
            (WebCore::SelectionController::currentForm):
            (WebCore::SelectionController::revealSelection):
            (WebCore::SelectionController::setSelectionFromNone):
            (WebCore::SelectionController::shouldChangeSelection):
            * editing/SelectionController.h:
            Moved functions here from Frame.
    
            * page/Frame.cpp:
            * page/Frame.h:
            Moved functions to SelectionController.
            Reorganized header to be easier to read and a bit more logical.
    
            * WebCore.exp.in: Updated.
    
            * dom/Document.cpp:
            (WebCore::Document::nodeChildrenWillBeRemoved):
            (WebCore::Document::nodeWillBeRemoved):
            Call Page::dragCaretController directly.
    
            * dom/Element.cpp:
            (WebCore::Element::updateFocusAppearance):
            * dom/InputElement.cpp:
            (WebCore::InputElement::updateFocusAppearance):
            * editing/ApplyStyleCommand.cpp:
            (WebCore::ApplyStyleCommand::editingStyleAtPosition):
            * editing/DeleteSelectionCommand.cpp:
            (WebCore::DeleteSelectionCommand::calculateTypingStyleAfterDelete):
            * editing/Editor.cpp:
            (WebCore::Editor::canSmartCopyOrDelete):
            (WebCore::Editor::textDirectionForSelection):
            (WebCore::Editor::appliedEditing):
            (WebCore::Editor::insertTextWithoutSendingTextEvent):
            (WebCore::Editor::advanceToNextMisspelling):
            (WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges):
            (WebCore::Editor::revealSelectionAfterEditingOperation):
            (WebCore::Editor::transpose):
            (WebCore::Editor::changeSelectionAfterCommand):
            (WebCore::Editor::computeAndSetTypingStyle):
            (WebCore::Editor::selectionComputedStyle):
            (WebCore::Editor::styleForSelectionStart):
            (WebCore::Editor::findString):
            * editing/EditorCommand.cpp:
            (WebCore::executeDelete):
            * editing/InsertLineBreakCommand.cpp:
            (WebCore::InsertLineBreakCommand::doApply):
            * editing/InsertTextCommand.cpp:
            (WebCore::InsertTextCommand::input):
            * editing/RemoveFormatCommand.cpp:
            (WebCore::RemoveFormatCommand::doApply):
            * editing/ReplaceSelectionCommand.cpp:
            (WebCore::ReplaceSelectionCommand::doApply):
            * editing/TypingCommand.cpp:
            (WebCore::TypingCommand::insertTextRunWithoutNewlines):
            (WebCore::TypingCommand::deleteKeyPressed):
            (WebCore::TypingCommand::forwardDeleteKeyPressed):
            * html/HTMLTextAreaElement.cpp:
            (WebCore::HTMLTextAreaElement::updateFocusAppearance):
            * page/ContextMenuController.cpp:
            (WebCore::ContextMenuController::contextMenuItemSelected):
            * page/DragController.cpp:
            (WebCore::DragController::concludeEditDrag):
            (WebCore::dragLocForSelectionDrag):
            * page/EventHandler.cpp:
            (WebCore::EventHandler::selectClosestWordFromMouseEvent):
            (WebCore::EventHandler::selectClosestWordOrLinkFromMouseEvent):
            (WebCore::EventHandler::handleMousePressEventTripleClick):
            (WebCore::EventHandler::handleMousePressEventSingleClick):
            (WebCore::EventHandler::updateSelectionForMouseDrag):
            (WebCore::EventHandler::handleMouseReleaseEvent):
            * page/FocusController.cpp:
            (WebCore::FocusController::advanceFocusInDocumentOrder):
            * page/chromium/EventHandlerChromium.cpp:
            (WebCore::EventHandler::passMousePressEventToSubframe):
            * page/chromium/FrameChromium.cpp:
            (WebCore::Frame::dragImageForSelection):
            * page/mac/FrameMac.mm:
            (WebCore::Frame::selectionImage):
            * platform/mac/ClipboardMac.mm:
            (WebCore::ClipboardMac::writeRange):
            * rendering/RenderBlock.cpp:
            (WebCore::RenderBlock::paintCaret):
            Call functions on selection().
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@67238 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index c4c3af5..9ba7236 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,109 @@
+2010-09-09  Darin Adler  <darin at apple.com>
+
+        Reviewed by Adam Barth.
+
+        Move functions from Frame to SelectionController as planned
+        https://bugs.webkit.org/show_bug.cgi?id=45508
+
+        Also removed Frame::dragCaretController since it just called Page::dragCaretController.
+
+        * editing/SelectionController.cpp:
+        (WebCore::SelectionController::setSelection):
+        (WebCore::SelectionController::modify):
+        (WebCore::SelectionController::selectFrameElementInParentIfFullySelected):
+        (WebCore::SelectionController::selectAll):
+        (WebCore::SelectionController::focusedOrActiveStateChanged):
+        (WebCore::SelectionController::notifyRendererOfSelectionChange):
+        (WebCore::isFrameElement):
+        (WebCore::SelectionController::setFocusedNodeIfNeeded):
+        (WebCore::SelectionController::paintDragCaret):
+        (WebCore::SelectionController::shouldDeleteSelection):
+        (WebCore::SelectionController::selectionBounds):
+        (WebCore::SelectionController::selectionTextRects):
+        (WebCore::scanForForm):
+        (WebCore::SelectionController::currentForm):
+        (WebCore::SelectionController::revealSelection):
+        (WebCore::SelectionController::setSelectionFromNone):
+        (WebCore::SelectionController::shouldChangeSelection):
+        * editing/SelectionController.h:
+        Moved functions here from Frame.
+
+        * page/Frame.cpp:
+        * page/Frame.h:
+        Moved functions to SelectionController.
+        Reorganized header to be easier to read and a bit more logical.
+
+        * WebCore.exp.in: Updated.
+
+        * dom/Document.cpp:
+        (WebCore::Document::nodeChildrenWillBeRemoved):
+        (WebCore::Document::nodeWillBeRemoved):
+        Call Page::dragCaretController directly.
+
+        * dom/Element.cpp:
+        (WebCore::Element::updateFocusAppearance):
+        * dom/InputElement.cpp:
+        (WebCore::InputElement::updateFocusAppearance):
+        * editing/ApplyStyleCommand.cpp:
+        (WebCore::ApplyStyleCommand::editingStyleAtPosition):
+        * editing/DeleteSelectionCommand.cpp:
+        (WebCore::DeleteSelectionCommand::calculateTypingStyleAfterDelete):
+        * editing/Editor.cpp:
+        (WebCore::Editor::canSmartCopyOrDelete):
+        (WebCore::Editor::textDirectionForSelection):
+        (WebCore::Editor::appliedEditing):
+        (WebCore::Editor::insertTextWithoutSendingTextEvent):
+        (WebCore::Editor::advanceToNextMisspelling):
+        (WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges):
+        (WebCore::Editor::revealSelectionAfterEditingOperation):
+        (WebCore::Editor::transpose):
+        (WebCore::Editor::changeSelectionAfterCommand):
+        (WebCore::Editor::computeAndSetTypingStyle):
+        (WebCore::Editor::selectionComputedStyle):
+        (WebCore::Editor::styleForSelectionStart):
+        (WebCore::Editor::findString):
+        * editing/EditorCommand.cpp:
+        (WebCore::executeDelete):
+        * editing/InsertLineBreakCommand.cpp:
+        (WebCore::InsertLineBreakCommand::doApply):
+        * editing/InsertTextCommand.cpp:
+        (WebCore::InsertTextCommand::input):
+        * editing/RemoveFormatCommand.cpp:
+        (WebCore::RemoveFormatCommand::doApply):
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::doApply):
+        * editing/TypingCommand.cpp:
+        (WebCore::TypingCommand::insertTextRunWithoutNewlines):
+        (WebCore::TypingCommand::deleteKeyPressed):
+        (WebCore::TypingCommand::forwardDeleteKeyPressed):
+        * html/HTMLTextAreaElement.cpp:
+        (WebCore::HTMLTextAreaElement::updateFocusAppearance):
+        * page/ContextMenuController.cpp:
+        (WebCore::ContextMenuController::contextMenuItemSelected):
+        * page/DragController.cpp:
+        (WebCore::DragController::concludeEditDrag):
+        (WebCore::dragLocForSelectionDrag):
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::selectClosestWordFromMouseEvent):
+        (WebCore::EventHandler::selectClosestWordOrLinkFromMouseEvent):
+        (WebCore::EventHandler::handleMousePressEventTripleClick):
+        (WebCore::EventHandler::handleMousePressEventSingleClick):
+        (WebCore::EventHandler::updateSelectionForMouseDrag):
+        (WebCore::EventHandler::handleMouseReleaseEvent):
+        * page/FocusController.cpp:
+        (WebCore::FocusController::advanceFocusInDocumentOrder):
+        * page/chromium/EventHandlerChromium.cpp:
+        (WebCore::EventHandler::passMousePressEventToSubframe):
+        * page/chromium/FrameChromium.cpp:
+        (WebCore::Frame::dragImageForSelection):
+        * page/mac/FrameMac.mm:
+        (WebCore::Frame::selectionImage):
+        * platform/mac/ClipboardMac.mm:
+        (WebCore::ClipboardMac::writeRange):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::paintCaret):
+        Call functions on selection().
+
 2010-09-10  Justin Schuh  <jschuh at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/WebCore.exp.in b/WebCore/WebCore.exp.in
index 265f42d..3a808fc 100644
--- a/WebCore/WebCore.exp.in
+++ b/WebCore/WebCore.exp.in
@@ -341,7 +341,6 @@ __ZN7WebCore15DatabaseTracker9setClientEPNS_21DatabaseTrackerClientE
 __ZN7WebCore15FocusController10setFocusedEb
 __ZN7WebCore15FocusController15setFocusedFrameEN3WTF10PassRefPtrINS_5FrameEEE
 __ZN7WebCore15FocusController15setInitialFocusENS_14FocusDirectionEPNS_13KeyboardEventE
-__ZNK7WebCore15FocusController18focusedOrMainFrameEv
 __ZN7WebCore15FocusController9setActiveEb
 __ZN7WebCore15GraphicsContext12setFillColorERKNS_5ColorENS_10ColorSpaceE
 __ZN7WebCore15GraphicsContext4clipERKNS_9FloatRectE
@@ -423,7 +422,9 @@ __ZN7WebCore19ResourceRequestBase19addHTTPHeaderFieldsERKNS_13HTTPHeaderMapE
 __ZN7WebCore19ResourceRequestBase6setURLERKNS_4KURLE
 __ZN7WebCore19SelectionController10setFocusedEb
 __ZN7WebCore19SelectionController12setSelectionERKNS_16VisibleSelectionEbbbNS0_19CursorAlignOnScrollENS_15TextGranularityENS_20DirectionalityPolicyE
+__ZN7WebCore19SelectionController15revealSelectionERKNS_15ScrollAlignmentEb
 __ZN7WebCore19SelectionController16setSelectedRangeEPNS_5RangeENS_9EAffinityEb
+__ZN7WebCore19SelectionController20setSelectionFromNoneEv
 __ZN7WebCore19SelectionController5clearEv
 __ZN7WebCore19SelectionController6modifyENS0_11EAlterationENS0_10EDirectionENS_15TextGranularityEb
 __ZN7WebCore19SelectionController9selectAllEv
@@ -580,8 +581,6 @@ __ZN7WebCore5Cache13getStatisticsEv
 __ZN7WebCore5Cache13setCapacitiesEjjj
 __ZN7WebCore5Frame10createViewERKNS_7IntSizeERKNS_5ColorEbS3_bNS_13ScrollbarModeEbS7_b
 __ZN7WebCore5Frame14frameForWidgetEPKNS_6WidgetE
-__ZN7WebCore5Frame15revealSelectionERKNS_15ScrollAlignmentEb
-__ZN7WebCore5Frame20setSelectionFromNoneEv
 __ZN7WebCore5Frame23visiblePositionForPointERKNS_8IntPointE
 __ZN7WebCore5Frame25matchLabelsAgainstElementEP7NSArrayPNS_7ElementE
 __ZN7WebCore5Frame28searchForLabelsBeforeElementEP7NSArrayPNS_7ElementEPmPb
@@ -934,6 +933,7 @@ __ZNK7WebCore14RenderListItem10markerTextEv
 __ZNK7WebCore14ResourceHandle10connectionEv
 __ZNK7WebCore14ResourceLoader11frameLoaderEv
 __ZNK7WebCore14SecurityOrigin5equalEPKS0_
+__ZNK7WebCore15FocusController18focusedOrMainFrameEv
 __ZNK7WebCore15GraphicsContext15platformContextEv
 __ZNK7WebCore15GraphicsContext16paintingDisabledEv
 __ZNK7WebCore15ProgressTracker17estimatedProgressEv
@@ -956,8 +956,11 @@ __ZNK7WebCore19AnimationController24numberOfActiveAnimationsEv
 __ZNK7WebCore19ResourceRequestBase10httpMethodEv
 __ZNK7WebCore19ResourceRequestBase3urlEv
 __ZNK7WebCore19ResourceRequestBase7isEmptyEv
+__ZNK7WebCore19SelectionController11currentFormEv
 __ZNK7WebCore19SelectionController17isInPasswordFieldEv
 __ZNK7WebCore19SelectionController18isFocusedAndActiveEv
+__ZNK7WebCore19SelectionController31getClippedVisibleTextRectanglesERN3WTF6VectorINS_9FloatRectELm0EEE
+__ZNK7WebCore19SelectionController6boundsEb
 __ZNK7WebCore20ResourceResponseBase14httpStatusCodeEv
 __ZNK7WebCore20ResourceResponseBase14httpStatusTextEv
 __ZNK7WebCore20ResourceResponseBase15httpHeaderFieldEPKc
@@ -988,15 +991,11 @@ __ZNK7WebCore4Page10pluginDataEv
 __ZNK7WebCore4Page15backForwardListEv
 __ZNK7WebCore4Page34inLowQualityImageInterpolationModeEv
 __ZNK7WebCore4Page9groupNameEv
-__ZNK7WebCore5Frame11currentFormEv
 __ZNK7WebCore5Frame13ownerRendererEv
 __ZNK7WebCore5Frame14selectionImageEb
 __ZNK7WebCore5Frame15contentRendererEv
 __ZNK7WebCore5Frame15layerTreeAsTextEv
-__ZNK7WebCore5Frame15selectionBoundsEb
 __ZNK7WebCore5Frame18documentTypeStringEv
-__ZNK7WebCore5Frame18selectionTextRectsERN3WTF6VectorINS_9FloatRectELm0EEENS0_30SelectionRectRespectTransformsEb
-__ZNK7WebCore5Frame20selectionGranularityEv
 __ZNK7WebCore5Frame8settingsEv
 __ZNK7WebCore5Frame9domWindowEv
 __ZNK7WebCore5Range11startOffsetERi
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 1c3cc1c..b04a209 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -3262,7 +3262,7 @@ void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
     if (Frame* frame = this->frame()) {
         for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
             frame->selection()->nodeWillBeRemoved(n);
-            frame->dragCaretController()->nodeWillBeRemoved(n);
+            frame->page()->dragCaretController()->nodeWillBeRemoved(n);
         }
     }
 }
@@ -3281,7 +3281,7 @@ void Document::nodeWillBeRemoved(Node* n)
 
     if (Frame* frame = this->frame()) {
         frame->selection()->nodeWillBeRemoved(n);
-        frame->dragCaretController()->nodeWillBeRemoved(n);
+        frame->page()->dragCaretController()->nodeWillBeRemoved(n);
     }
     
 #if ENABLE(FULLSCREEN_API)
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 6ff47e0..54dad27 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -1347,9 +1347,9 @@ void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
         // FIXME: We should restore the previous selection if there is one.
         VisibleSelection newSelection = VisibleSelection(Position(this, 0), DOWNSTREAM);
         
-        if (frame->shouldChangeSelection(newSelection)) {
+        if (frame->selection()->shouldChangeSelection(newSelection)) {
             frame->selection()->setSelection(newSelection);
-            frame->revealSelection();
+            frame->selection()->revealSelection();
         }
     } else if (renderer() && !renderer()->isWidget())
         renderer()->enclosingLayer()->scrollRectToVisible(getRect());
diff --git a/WebCore/dom/InputElement.cpp b/WebCore/dom/InputElement.cpp
index f0284d8..b2a9714 100644
--- a/WebCore/dom/InputElement.cpp
+++ b/WebCore/dom/InputElement.cpp
@@ -99,7 +99,7 @@ void InputElement::updateFocusAppearance(InputElementData& data, InputElement* i
 
     Document* document = element->document();
     if (document && document->frame())
-        document->frame()->revealSelection();
+        document->frame()->selection()->revealSelection();
 }
 
 void InputElement::updateSelectionRange(InputElement* inputElement, Element* element, int start, int end)
diff --git a/WebCore/editing/ApplyStyleCommand.cpp b/WebCore/editing/ApplyStyleCommand.cpp
index d104cbe..69dc619 100644
--- a/WebCore/editing/ApplyStyleCommand.cpp
+++ b/WebCore/editing/ApplyStyleCommand.cpp
@@ -464,7 +464,7 @@ PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::editingStyleAtPosition
     }
 
     if (shouldIncludeTypingStyle == IncludeTypingStyle) {
-        CSSMutableStyleDeclaration* typingStyle = pos.node()->document()->frame()->typingStyle();
+        CSSMutableStyleDeclaration* typingStyle = pos.node()->document()->frame()->selection()->typingStyle();
         if (typingStyle)
             style->merge(typingStyle);
     }
diff --git a/WebCore/editing/DeleteSelectionCommand.cpp b/WebCore/editing/DeleteSelectionCommand.cpp
index 70f0e88..4aa5c3c 100644
--- a/WebCore/editing/DeleteSelectionCommand.cpp
+++ b/WebCore/editing/DeleteSelectionCommand.cpp
@@ -714,7 +714,7 @@ void DeleteSelectionCommand::calculateTypingStyleAfterDelete()
     // In this case if we start typing, the new characters should have the same style as the just deleted ones,
     // but, if we change the selection, come back and start typing that style should be lost.  Also see 
     // preserveTypingStyle() below.
-    document()->frame()->setTypingStyle(m_typingStyle.get());
+    document()->frame()->selection()->setTypingStyle(m_typingStyle);
 }
 
 void DeleteSelectionCommand::clearTransientState()
diff --git a/WebCore/editing/Editor.cpp b/WebCore/editing/Editor.cpp
index c515bfc..34fd99a 100644
--- a/WebCore/editing/Editor.cpp
+++ b/WebCore/editing/Editor.cpp
@@ -257,7 +257,7 @@ bool Editor::smartInsertDeleteEnabled()
     
 bool Editor::canSmartCopyOrDelete()
 {
-    return client() && client()->smartInsertDeleteEnabled() && m_frame->selectionGranularity() == WordGranularity;
+    return client() && client()->smartInsertDeleteEnabled() && m_frame->selection()->granularity() == WordGranularity;
 }
 
 bool Editor::isSelectTrailingWhitespaceEnabled()
@@ -551,7 +551,7 @@ WritingDirection Editor::textDirectionForSelection(bool& hasNestedOrMultipleEmbe
     }
 
     if (m_frame->selection()->isCaret()) {
-        if (CSSMutableStyleDeclaration* typingStyle = m_frame->typingStyle()) {
+        if (CSSMutableStyleDeclaration* typingStyle = m_frame->selection()->typingStyle()) {
             RefPtr<CSSValue> unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
             if (unicodeBidi) {
                 ASSERT(unicodeBidi->isPrimitiveValue());
@@ -1011,7 +1011,7 @@ void Editor::appliedEditing(PassRefPtr<EditCommand> cmd)
     changeSelectionAfterCommand(newSelection, false, false);
         
     if (!cmd->preservesTypingStyle())
-        m_frame->setTypingStyle(0);
+        m_frame->selection()->clearTypingStyle();
     
     // Command will be equal to last edit command only in the case of typing
     if (m_lastEditCommand.get() == cmd)
@@ -1116,7 +1116,7 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
             // Reveal the current selection 
             if (Frame* editedFrame = document->frame())
                 if (Page* page = editedFrame->page())
-                    page->focusController()->focusedOrMainFrame()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
+                    page->focusController()->focusedOrMainFrame()->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
         }
     }
 
@@ -2132,7 +2132,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
         // FIXME 4859190: This gets confused with doubled punctuation at the end of a paragraph
         RefPtr<Range> badGrammarRange = TextIterator::subrange(grammarSearchRange.get(), grammarPhraseOffset + grammarDetail.location, grammarDetail.length);
         frame()->selection()->setSelection(VisibleSelection(badGrammarRange.get(), SEL_DEFAULT_AFFINITY));
-        frame()->revealSelection();
+        frame()->selection()->revealSelection();
         
         client()->updateSpellingUIWithGrammarString(badGrammarPhrase, grammarDetail);
         frame()->document()->markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, grammarDetail.userDescription);
@@ -2143,7 +2143,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
         
         RefPtr<Range> misspellingRange = TextIterator::subrange(spellingSearchRange.get(), misspellingOffset, misspelledWord.length());
         frame()->selection()->setSelection(VisibleSelection(misspellingRange.get(), DOWNSTREAM));
-        frame()->revealSelection();
+        frame()->selection()->revealSelection();
         
         client()->updateSpellingUIWithMisspelledWord(misspelledWord);
         frame()->document()->markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
@@ -2435,7 +2435,7 @@ void Editor::markMisspellingsAfterTypingToPosition(const VisiblePosition &p)
     if (!autocorrectedString.isEmpty()) {
         VisibleSelection newSelection(misspellingRange.get(), DOWNSTREAM);
         if (newSelection != frame()->selection()->selection()) {
-            if (!frame()->shouldChangeSelection(newSelection))
+            if (!frame()->selection()->shouldChangeSelection(newSelection))
                 return;
             frame()->selection()->setSelection(newSelection);
         }
@@ -2709,7 +2709,7 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingOptions textCh
                 }
             }
             if (doReplacement && !shouldShowCorrectionPanel && selectionToReplace != m_frame->selection()->selection()) {
-                if (m_frame->shouldChangeSelection(selectionToReplace)) {
+                if (m_frame->selection()->shouldChangeSelection(selectionToReplace)) {
                     m_frame->selection()->setSelection(selectionToReplace);
                     selectionChanged = true;
                 } else {
@@ -2875,7 +2875,7 @@ void Editor::revealSelectionAfterEditingOperation()
     if (m_ignoreCompositionSelectionChange)
         return;
 
-    m_frame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
+    m_frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
 }
 
 void Editor::setIgnoreCompositionSelectionChange(bool ignore)
@@ -2952,7 +2952,7 @@ void Editor::transpose()
 
     // Select the two characters.
     if (newSelection != m_frame->selection()->selection()) {
-        if (!m_frame->shouldChangeSelection(newSelection))
+        if (!m_frame->selection()->shouldChangeSelection(newSelection))
             return;
         m_frame->selection()->setSelection(newSelection);
     }
@@ -3125,7 +3125,7 @@ void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection, b
     // The old selection can be invalid here and calling shouldChangeSelection can produce some strange calls.
     // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain Ranges for selections that are no longer valid
     bool selectionDidNotChangeDOMPosition = newSelection == m_frame->selection()->selection();
-    if (selectionDidNotChangeDOMPosition || m_frame->shouldChangeSelection(newSelection))
+    if (selectionDidNotChangeDOMPosition || m_frame->selection()->shouldChangeSelection(newSelection))
         m_frame->selection()->setSelection(newSelection, closeTyping, clearTypingStyle);
         
     // Some editing operations change the selection visually without affecting its position within the DOM.
@@ -3196,18 +3196,18 @@ bool Editor::shouldChangeSelection(const VisibleSelection& oldSelection, const V
     return client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(), affinity, stillSelecting);
 }
 
-void Editor::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction)
+void Editor::computeAndSetTypingStyle(CSSStyleDeclaration* style, EditAction editingAction)
 {
     if (!style || !style->length()) {
-        m_frame->clearTypingStyle();
+        m_frame->selection()->clearTypingStyle();
         return;
     }
 
     // Calculate the current typing style.
     RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
-    if (m_frame->typingStyle()) {
-        m_frame->typingStyle()->merge(mutableStyle.get());
-        mutableStyle = m_frame->typingStyle();
+    if (m_frame->selection()->typingStyle()) {
+        m_frame->selection()->typingStyle()->merge(mutableStyle.get());
+        mutableStyle = m_frame->selection()->typingStyle();
     }
 
     RefPtr<CSSValue> unicodeBidi;
@@ -3236,7 +3236,7 @@ void Editor::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction edi
         applyCommand(ApplyStyleCommand::create(m_frame->document(), blockStyle.get(), editingAction));
 
     // Set the remaining style as the typing style.
-    m_frame->setTypingStyle(mutableStyle.get());
+    m_frame->selection()->setTypingStyle(mutableStyle.release());
 }
 
 PassRefPtr<CSSComputedStyleDeclaration> Editor::selectionComputedStyle(Node*& nodeToRemove) const
@@ -3264,10 +3264,10 @@ PassRefPtr<CSSComputedStyleDeclaration> Editor::selectionComputedStyle(Node*& no
     RefPtr<Element> styleElement = element;
     ExceptionCode ec = 0;
 
-    if (m_frame->typingStyle()) {
+    if (m_frame->selection()->typingStyle()) {
         styleElement = m_frame->document()->createElement(spanTag, false);
 
-        styleElement->setAttribute(styleAttr, m_frame->typingStyle()->cssText().impl(), ec);
+        styleElement->setAttribute(styleAttr, m_frame->selection()->typingStyle()->cssText(), ec);
         ASSERT(!ec);
 
         styleElement->appendChild(m_frame->document()->createEditingTextNode(""), ec);
@@ -3368,13 +3368,13 @@ RenderStyle* Editor::styleForSelectionStart(Node *&nodeToRemove) const
     if (!position.node())
         return 0;
 
-    if (!m_frame->typingStyle())
+    if (!m_frame->selection()->typingStyle())
         return position.node()->renderer()->style();
 
     RefPtr<Element> styleElement = m_frame->document()->createElement(spanTag, false);
 
     ExceptionCode ec = 0;
-    String styleText = m_frame->typingStyle()->cssText() + " display: inline";
+    String styleText = m_frame->selection()->typingStyle()->cssText() + " display: inline";
     styleElement->setAttribute(styleAttr, styleText.impl(), ec);
     ASSERT(!ec);
 
@@ -3471,7 +3471,7 @@ bool Editor::findString(const String& target, bool forward, bool caseFlag, bool
         return false;
 
     m_frame->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM));
-    m_frame->revealSelection();
+    m_frame->selection()->revealSelection();
     return true;
 }
 
diff --git a/WebCore/editing/EditorCommand.cpp b/WebCore/editing/EditorCommand.cpp
index 4f53ae9..24ceb39 100644
--- a/WebCore/editing/EditorCommand.cpp
+++ b/WebCore/editing/EditorCommand.cpp
@@ -322,7 +322,7 @@ static bool executeDelete(Frame* frame, Event*, EditorCommandSource source, cons
     case CommandFromDOMWithUserInterface:
         // If the current selection is a caret, delete the preceding character. IE performs forwardDelete, but we currently side with Firefox.
         // Doesn't scroll to make the selection visible, or modify the kill ring (this time, siding with IE, not Firefox).
-        TypingCommand::deleteKeyPressed(frame->document(), frame->selectionGranularity() == WordGranularity);
+        TypingCommand::deleteKeyPressed(frame->document(), frame->selection()->granularity() == WordGranularity);
         return true;
     }
     ASSERT_NOT_REACHED();
diff --git a/WebCore/editing/InsertLineBreakCommand.cpp b/WebCore/editing/InsertLineBreakCommand.cpp
index dbe4b39..8ac1167 100644
--- a/WebCore/editing/InsertLineBreakCommand.cpp
+++ b/WebCore/editing/InsertLineBreakCommand.cpp
@@ -165,7 +165,7 @@ void InsertLineBreakCommand::doApply()
 
     // Handle the case where there is a typing style.
     
-    CSSMutableStyleDeclaration* typingStyle = document()->frame()->typingStyle();
+    CSSMutableStyleDeclaration* typingStyle = document()->frame()->selection()->typingStyle();
     
     if (typingStyle && typingStyle->length() > 0) {
         // Apply the typing style to the inserted line break, so that if the selection
diff --git a/WebCore/editing/InsertTextCommand.cpp b/WebCore/editing/InsertTextCommand.cpp
index cfaf219..b6c8236 100644
--- a/WebCore/editing/InsertTextCommand.cpp
+++ b/WebCore/editing/InsertTextCommand.cpp
@@ -190,7 +190,7 @@ void InsertTextCommand::input(const String& text, bool selectInsertedText)
     setEndingSelection(forcedEndingSelection);
 
     // Handle the case where there is a typing style.
-    CSSMutableStyleDeclaration* typingStyle = document()->frame()->typingStyle();
+    CSSMutableStyleDeclaration* typingStyle = document()->frame()->selection()->typingStyle();
     RefPtr<CSSComputedStyleDeclaration> endingStyle = endPosition.computedStyle();
     RefPtr<CSSValue> unicodeBidi;
     RefPtr<CSSValue> direction;
diff --git a/WebCore/editing/RemoveFormatCommand.cpp b/WebCore/editing/RemoveFormatCommand.cpp
index 257172b..65f6008 100644
--- a/WebCore/editing/RemoveFormatCommand.cpp
+++ b/WebCore/editing/RemoveFormatCommand.cpp
@@ -78,7 +78,7 @@ void RemoveFormatCommand::doApply()
     
     // Insert the content with the default style.
     // See <rdar://problem/5794382> RemoveFormat doesn't always reset text alignment
-    frame->setTypingStyle(defaultStyle.get());
+    frame->selection()->setTypingStyle(defaultStyle.release());
     
     inputText(string, true);
 }
diff --git a/WebCore/editing/ReplaceSelectionCommand.cpp b/WebCore/editing/ReplaceSelectionCommand.cpp
index 38f3ed2..e754aef 100644
--- a/WebCore/editing/ReplaceSelectionCommand.cpp
+++ b/WebCore/editing/ReplaceSelectionCommand.cpp
@@ -898,7 +898,7 @@ void ReplaceSelectionCommand::doApply()
     // FIXME: Can this wait until after the operation has been performed?  There doesn't seem to be
     // any work performed after this that queries or uses the typing style.
     if (Frame* frame = document()->frame())
-        frame->clearTypingStyle();
+        frame->selection()->clearTypingStyle();
     
     bool handledStyleSpans = handleStyleSpansBeforeInsertion(fragment, insertionPos);
 
diff --git a/WebCore/editing/SelectionController.cpp b/WebCore/editing/SelectionController.cpp
index 99b2224..1a0c031 100644
--- a/WebCore/editing/SelectionController.cpp
+++ b/WebCore/editing/SelectionController.cpp
@@ -29,6 +29,7 @@
 #include "DeleteSelectionCommand.h"
 #include "Document.h"
 #include "Editor.h"
+#include "EditorClient.h"
 #include "Element.h"
 #include "EventHandler.h"
 #include "ExceptionCode.h"
@@ -38,7 +39,8 @@
 #include "FrameTree.h"
 #include "FrameView.h"
 #include "GraphicsContext.h"
-#include "HTMLFrameOwnerElement.h"
+#include "HTMLFormElement.h"
+#include "HTMLFrameElementBase.h"
 #include "HTMLInputElement.h"
 #include "HTMLNames.h"
 #include "HitTestRequest.h"
@@ -46,8 +48,10 @@
 #include "Page.h"
 #include "Range.h"
 #include "RenderLayer.h"
+#include "RenderTextControl.h"
 #include "RenderTheme.h"
 #include "RenderView.h"
+#include "RenderWidget.h"
 #include "SecureTextInput.h"
 #include "Settings.h"
 #include "TextIterator.h"
@@ -107,7 +111,7 @@ void SelectionController::moveTo(const Position &base, const Position &extent, E
     setSelection(VisibleSelection(base, extent, affinity), true, true, userTriggered);
 }
 
-void SelectionController::setSelection(const VisibleSelection& s, bool closeTyping, bool clearTypingStyle, bool userTriggered, CursorAlignOnScroll align, TextGranularity granularity, DirectionalityPolicy directionalityPolicy)
+void SelectionController::setSelection(const VisibleSelection& s, bool closeTyping, bool shouldClearTypingStyle, bool userTriggered, CursorAlignOnScroll align, TextGranularity granularity, DirectionalityPolicy directionalityPolicy)
 {
     m_granularity = granularity;
 
@@ -134,15 +138,15 @@ void SelectionController::setSelection(const VisibleSelection& s, bool closeTypi
     // <http://bugs.webkit.org/show_bug.cgi?id=23464>: Infinite recursion at SelectionController::setSelection
     // if document->frame() == m_frame we can get into an infinite loop
     if (document && document->frame() && document->frame() != m_frame && document != m_frame->document()) {
-        document->frame()->selection()->setSelection(s, closeTyping, clearTypingStyle, userTriggered);
+        document->frame()->selection()->setSelection(s, closeTyping, shouldClearTypingStyle, userTriggered);
         return;
     }
     
     if (closeTyping)
         TypingCommand::closeTyping(m_frame->editor()->lastEditCommand());
 
-    if (clearTypingStyle)
-        m_frame->clearTypingStyle();
+    if (shouldClearTypingStyle)
+        clearTypingStyle();
         
     if (m_selection == s)
         return;
@@ -154,7 +158,7 @@ void SelectionController::setSelection(const VisibleSelection& s, bool closeTypi
     m_caretRectNeedsUpdate = true;
     
     if (!s.isNone())
-        m_frame->setFocusedNodeIfNeeded();
+        setFocusedNodeIfNeeded();
     
     updateAppearance();
 
@@ -162,7 +166,7 @@ void SelectionController::setSelection(const VisibleSelection& s, bool closeTypi
     // It will be restored by the vertical arrow navigation code if necessary.
     m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation;
     selectFrameElementInParentIfFullySelected();
-    m_frame->notifyRendererOfSelectionChange(userTriggered);
+    notifyRendererOfSelectionChange(userTriggered);
     m_frame->editor()->respondToChangedSelection(oldSelection, closeTyping);
     if (userTriggered) {
         ScrollAlignment alignment;
@@ -172,7 +176,7 @@ void SelectionController::setSelection(const VisibleSelection& s, bool closeTypi
         else
             alignment = (align == AlignCursorOnScrollAlways) ? ScrollAlignment::alignTopAlways : ScrollAlignment::alignToEdgeIfNeeded;
 
-        m_frame->revealSelection(alignment, true);
+        revealSelection(alignment, true);
     }
 
     notifyAccessibilityForSelectionChange();
@@ -287,8 +291,7 @@ void SelectionController::willBeModified(EAlteration alter, EDirection direction
 
 TextDirection SelectionController::directionOfEnclosingBlock()
 {
-    Node* n = m_selection.extent().node();
-    Node* enclosingBlockNode = enclosingBlock(n);
+    Node* enclosingBlockNode = enclosingBlock(m_selection.extent().node());
     if (!enclosingBlockNode)
         return LTR;
     RenderObject* renderer = enclosingBlockNode->renderer();
@@ -638,7 +641,7 @@ bool SelectionController::modify(EAlteration alter, EDirection direction, TextGr
         trialSelectionController.setIsDirectional(m_isDirectional);
         trialSelectionController.modify(alter, direction, granularity, false, settings);
 
-        bool change = m_frame->shouldChangeSelection(trialSelectionController.selection());
+        bool change = shouldChangeSelection(trialSelectionController.selection());
         if (!change)
             return false;
     }
@@ -734,7 +737,7 @@ bool SelectionController::modify(EAlteration alter, int verticalDistance, bool u
         trialSelectionController.setIsDirectional(m_isDirectional);
         trialSelectionController.modify(alter, verticalDistance, false);
 
-        bool change = m_frame->shouldChangeSelection(trialSelectionController.selection());
+        bool change = shouldChangeSelection(trialSelectionController.selection());
         if (!change)
             return false;
     }
@@ -1243,7 +1246,7 @@ void SelectionController::selectFrameElementInParentIfFullySelected()
 
     // Focus on the parent frame, and then select from before this element to after.
     VisibleSelection newSelection(beforeOwnerElement, afterOwnerElement);
-    if (parent->shouldChangeSelection(newSelection)) {
+    if (parent->selection()->shouldChangeSelection(newSelection)) {
         page->focusController()->setFocusedFrame(parent);
         parent->selection()->setSelection(newSelection);
     }
@@ -1269,10 +1272,10 @@ void SelectionController::selectAll()
     if (!root)
         return;
     VisibleSelection newSelection(VisibleSelection::selectionFromContentsOfNode(root));
-    if (m_frame->shouldChangeSelection(newSelection))
+    if (shouldChangeSelection(newSelection))
         setSelection(newSelection);
     selectFrameElementInParentIfFullySelected();
-    m_frame->notifyRendererOfSelectionChange(true);
+    notifyRendererOfSelectionChange(true);
 }
 
 bool SelectionController::setSelectedRange(Range* range, EAffinity affinity, bool closeTyping)
@@ -1347,11 +1350,11 @@ void SelectionController::focusedOrActiveStateChanged()
     // RenderObject::selectionForegroundColor() check if the frame is active,
     // we have to update places those colors were painted.
     if (RenderView* view = toRenderView(m_frame->document()->renderer()))
-        view->repaintRectangleInViewAndCompositedLayers(enclosingIntRect(m_frame->selectionBounds()));
+        view->repaintRectangleInViewAndCompositedLayers(enclosingIntRect(bounds()));
 
     // Caret appears in the active frame.
     if (activeAndFocused)
-        m_frame->setSelectionFromNone();
+        setSelectionFromNone();
     setCaretVisible(activeAndFocused);
 
     // Update for caps lock state
@@ -1502,6 +1505,207 @@ void SelectionController::caretBlinkTimerFired(Timer<SelectionController>*)
 #endif
 }
 
+void SelectionController::notifyRendererOfSelectionChange(bool userTriggered)
+{
+    m_frame->document()->updateStyleIfNeeded();
+
+    if (!rootEditableElement())
+        return;
+
+    RenderObject* renderer = rootEditableElement()->shadowAncestorNode()->renderer();
+    if (!renderer || !renderer->isTextControl())
+        return;
+
+    toRenderTextControl(renderer)->selectionChanged(userTriggered);
+}
+
+// Helper function that tells whether a particular node is an element that has an entire
+// Frame and FrameView, a <frame>, <iframe>, or <object>.
+static bool isFrameElement(const Node* n)
+{
+    if (!n)
+        return false;
+    RenderObject* renderer = n->renderer();
+    if (!renderer || !renderer->isWidget())
+        return false;
+    Widget* widget = toRenderWidget(renderer)->widget();
+    return widget && widget->isFrameView();
+}
+
+void SelectionController::setFocusedNodeIfNeeded()
+{
+    if (isNone() || !isFocused())
+        return;
+
+    bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
+    if (caretBrowsing) {
+        if (Node* anchor = enclosingAnchorElement(base())) {
+            m_frame->page()->focusController()->setFocusedNode(anchor, m_frame);
+            return;
+        }
+    }
+
+    if (Node* target = rootEditableElement()) {
+        RenderObject* renderer = target->renderer();
+
+        // Walk up the render tree to search for a node to focus.
+        // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
+        while (renderer) {
+            // We don't want to set focus on a subframe when selecting in a parent frame,
+            // so add the !isFrameElement check here. There's probably a better way to make this
+            // work in the long term, but this is the safest fix at this time.
+            if (target && target->isMouseFocusable() && !isFrameElement(target)) {
+                m_frame->page()->focusController()->setFocusedNode(target, m_frame);
+                return;
+            }
+            renderer = renderer->parent();
+            if (renderer)
+                target = renderer->node();
+        }
+        m_frame->document()->setFocusedNode(0);
+    }
+
+    if (caretBrowsing)
+        m_frame->page()->focusController()->setFocusedNode(0, m_frame);
+}
+
+void SelectionController::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
+{
+#if ENABLE(TEXT_CARET)
+    SelectionController* dragCaretController = m_frame->page()->dragCaretController();
+    ASSERT(dragCaretController->selection().isCaret());
+    if (dragCaretController->selection().start().node()->document()->frame() == m_frame)
+        dragCaretController->paintCaret(p, tx, ty, clipRect);
+#else
+    UNUSED_PARAM(p);
+    UNUSED_PARAM(tx);
+    UNUSED_PARAM(ty);
+    UNUSED_PARAM(clipRect);
+#endif
+}
+
+bool SelectionController::shouldDeleteSelection(const VisibleSelection& selection) const
+{
+    return m_frame->editor()->client()->shouldDeleteRange(selection.toNormalizedRange().get());
+}
+
+FloatRect SelectionController::bounds(bool clipToVisibleContent) const
+{
+    RenderView* root = m_frame->contentRenderer();
+    FrameView* view = m_frame->view();
+    if (!root || !view)
+        return IntRect();
+
+    IntRect selectionRect = root->selectionBounds(clipToVisibleContent);
+    return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
+}
+
+void SelectionController::getClippedVisibleTextRectangles(Vector<FloatRect>& rectangles) const
+{
+    RenderView* root = m_frame->contentRenderer();
+    if (!root)
+        return;
+
+    FloatRect visibleContentRect = m_frame->view()->visibleContentRect();
+
+    Vector<FloatQuad> quads;
+    toNormalizedRange()->textQuads(quads, true);
+
+    // FIXME: We are appending empty rectangles to the list for those that fall outside visibleContentRect.
+    // It might be better to omit those rectangles entirely.
+    size_t size = quads.size();
+    for (size_t i = 0; i < size; ++i)
+        rectangles.append(intersection(quads[i].enclosingBoundingBox(), visibleContentRect));
+}
+
+// Scans logically forward from "start", including any child frames.
+static HTMLFormElement* scanForForm(Node* start)
+{
+    for (Node* node = start; node; node = node->traverseNextNode()) {
+        if (node->hasTagName(formTag))
+            return static_cast<HTMLFormElement*>(node);
+        if (node->isHTMLElement() && static_cast<HTMLElement*>(node)->isFormControlElement())
+            return static_cast<HTMLFormControlElement*>(node)->form();
+        if (node->hasTagName(frameTag) || node->hasTagName(iframeTag)) {
+            Node* childDocument = static_cast<HTMLFrameElementBase*>(node)->contentDocument();
+            if (HTMLFormElement* frameResult = scanForForm(childDocument))
+                return frameResult;
+        }
+    }
+    return 0;
+}
+
+// We look for either the form containing the current focus, or for one immediately after it
+HTMLFormElement* SelectionController::currentForm() const
+{
+    // Start looking either at the active (first responder) node, or where the selection is.
+    Node* start = m_frame->document()->focusedNode();
+    if (!start)
+        start = this->start().node();
+
+    // Try walking up the node tree to find a form element.
+    Node* node;
+    for (node = start; node; node = node->parentNode()) {
+        if (node->hasTagName(formTag))
+            return static_cast<HTMLFormElement*>(node);
+        if (node->isHTMLElement() && static_cast<HTMLElement*>(node)->isFormControlElement())
+            return static_cast<HTMLFormControlElement*>(node)->form();
+    }
+
+    // Try walking forward in the node tree to find a form element.
+    return scanForForm(start);
+}
+
+void SelectionController::revealSelection(const ScrollAlignment& alignment, bool revealExtent)
+{
+    IntRect rect;
+
+    switch (selectionType()) {
+    case VisibleSelection::NoSelection:
+        return;
+    case VisibleSelection::CaretSelection:
+        rect = absoluteCaretBounds();
+        break;
+    case VisibleSelection::RangeSelection:
+        rect = revealExtent ? VisiblePosition(extent()).absoluteCaretBounds() : enclosingIntRect(bounds(false));
+        break;
+    }
+
+    Position start = this->start();
+    ASSERT(start.node());
+    if (start.node() && start.node()->renderer()) {
+        // FIXME: This code only handles scrolling the startContainer's layer, but
+        // the selection rect could intersect more than just that.
+        // See <rdar://problem/4799899>.
+        if (RenderLayer* layer = start.node()->renderer()->enclosingLayer()) {
+            layer->scrollRectToVisible(rect, false, alignment, alignment);
+            updateAppearance();
+        }
+    }
+}
+
+void SelectionController::setSelectionFromNone()
+{
+    // Put a caret inside the body if the entire frame is editable (either the
+    // entire WebView is editable or designMode is on for this document).
+
+    Document* document = m_frame->document();
+    bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
+    if (!isNone() || !(m_frame->isContentEditable() || caretBrowsing))
+        return;
+
+    Node* node = document->documentElement();
+    while (node && !node->hasTagName(bodyTag))
+        node = node->traverseNextNode();
+    if (node)
+        setSelection(VisibleSelection(Position(node, 0), DOWNSTREAM));
+}
+
+bool SelectionController::shouldChangeSelection(const VisibleSelection& newSelection) const
+{
+    return m_frame->editor()->shouldChangeSelection(selection(), newSelection, newSelection.affinity(), false);
+}
+
 #ifndef NDEBUG
 
 void SelectionController::formatForDebugger(char* buffer, unsigned length) const
diff --git a/WebCore/editing/SelectionController.h b/WebCore/editing/SelectionController.h
index 5fa2769..90018cd 100644
--- a/WebCore/editing/SelectionController.h
+++ b/WebCore/editing/SelectionController.h
@@ -26,8 +26,10 @@
 #ifndef SelectionController_h
 #define SelectionController_h
 
+#include "CSSMutableStyleDeclaration.h"
 #include "IntRect.h"
 #include "Range.h"
+#include "ScrollBehavior.h"
 #include "Timer.h"
 #include "VisibleSelection.h"
 #include <wtf/Noncopyable.h>
@@ -36,6 +38,7 @@ namespace WebCore {
 
 class Frame;
 class GraphicsContext;
+class HTMLFormElement;
 class RenderObject;
 class RenderView;
 class Settings;
@@ -149,6 +152,26 @@ public:
     void showTreeForThis() const;
 #endif
 
+    bool shouldChangeSelection(const VisibleSelection&) const;
+    bool shouldDeleteSelection(const VisibleSelection&) const;
+    void setFocusedNodeIfNeeded();
+    void notifyRendererOfSelectionChange(bool userTriggered);
+
+    void paintDragCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const;
+
+    CSSMutableStyleDeclaration* typingStyle() const;
+    void setTypingStyle(PassRefPtr<CSSMutableStyleDeclaration>);
+    void clearTypingStyle();
+
+    FloatRect bounds(bool clipToVisibleContent = true) const;
+
+    void getClippedVisibleTextRectangles(Vector<FloatRect>&) const;
+
+    HTMLFormElement* currentForm() const;
+
+    void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, bool revealExtent = false);
+    void setSelectionFromNone();
+
 private:
     enum EPositionType { START, END, BASE, EXTENT };
 
@@ -193,6 +216,8 @@ private:
     VisibleSelection m_selection;
     TextGranularity m_granularity;
 
+    RefPtr<CSSMutableStyleDeclaration> m_typingStyle;
+
     Timer<SelectionController> m_caretBlinkTimer;
 
     IntRect m_caretRect; // caret rect in coords local to the renderer responsible for painting the caret
@@ -209,6 +234,21 @@ private:
     bool m_caretPaint;
 };
 
+inline CSSMutableStyleDeclaration* SelectionController::typingStyle() const
+{
+    return m_typingStyle.get();
+}
+
+inline void SelectionController::clearTypingStyle()
+{
+    m_typingStyle.clear();
+}
+
+inline void SelectionController::setTypingStyle(PassRefPtr<CSSMutableStyleDeclaration> style)
+{
+    m_typingStyle = style;
+}
+
 #if !(PLATFORM(MAC) || PLATFORM(GTK))
 inline void SelectionController::notifyAccessibilityForSelectionChange()
 {
diff --git a/WebCore/editing/TypingCommand.cpp b/WebCore/editing/TypingCommand.cpp
index 81a6d5c..1d1183a 100644
--- a/WebCore/editing/TypingCommand.cpp
+++ b/WebCore/editing/TypingCommand.cpp
@@ -356,7 +356,7 @@ void TypingCommand::insertText(const String &text, bool selectInsertedText)
 void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool selectInsertedText)
 {
     RefPtr<InsertTextCommand> command;
-    if (!document()->frame()->typingStyle() && !m_commands.isEmpty()) {
+    if (!document()->frame()->selection()->typingStyle() && !m_commands.isEmpty()) {
         EditCommand* lastCommand = m_commands.last().get();
         if (lastCommand->isInsertTextCommand())
             command = static_cast<InsertTextCommand*>(lastCommand);
@@ -496,7 +496,7 @@ void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
     if (selectionToDelete.isNone())
         return;
     
-    if (selectionToDelete.isCaret() || !document()->frame()->shouldDeleteSelection(selectionToDelete))
+    if (selectionToDelete.isCaret() || !document()->frame()->selection()->shouldDeleteSelection(selectionToDelete))
         return;
     
     if (killRing)
@@ -579,7 +579,7 @@ void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool ki
     if (selectionToDelete.isNone())
         return;
     
-    if (selectionToDelete.isCaret() || !document()->frame()->shouldDeleteSelection(selectionToDelete))
+    if (selectionToDelete.isCaret() || !document()->frame()->selection()->shouldDeleteSelection(selectionToDelete))
         return;
         
     if (killRing)
diff --git a/WebCore/html/HTMLTextAreaElement.cpp b/WebCore/html/HTMLTextAreaElement.cpp
index e16697e..80e130d 100644
--- a/WebCore/html/HTMLTextAreaElement.cpp
+++ b/WebCore/html/HTMLTextAreaElement.cpp
@@ -222,7 +222,7 @@ void HTMLTextAreaElement::updateFocusAppearance(bool restorePreviousSelection)
     }
 
     if (document()->frame())
-        document()->frame()->revealSelection();
+        document()->frame()->selection()->revealSelection();
 }
 
 void HTMLTextAreaElement::defaultEventHandler(Event* event)
diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp
index 4ce17bd..d2317d2 100644
--- a/WebCore/page/ContextMenuController.cpp
+++ b/WebCore/page/ContextMenuController.cpp
@@ -231,7 +231,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
             Document* document = frame->document();
             RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""), true, false, true);
             applyCommand(command);
-            frame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
+            frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
         }
         break;
     case ContextMenuItemTagIgnoreSpelling:
diff --git a/WebCore/page/DragController.cpp b/WebCore/page/DragController.cpp
index c623bf6..b55b7a1 100644
--- a/WebCore/page/DragController.cpp
+++ b/WebCore/page/DragController.cpp
@@ -455,7 +455,7 @@ bool DragController::concludeEditDrag(DragData* dragData)
             // NSTextView behavior is to always smart delete on moving a selection,
             // but only to smart insert if the selection granularity is word granularity.
             bool smartDelete = innerFrame->editor()->smartInsertDeleteEnabled();
-            bool smartInsert = smartDelete && innerFrame->selectionGranularity() == WordGranularity && dragData->canSmartReplace();
+            bool smartInsert = smartDelete && innerFrame->selection()->granularity() == WordGranularity && dragData->canSmartReplace();
             applyCommand(MoveSelectionCommand::create(fragment, dragCaret.base(), smartInsert, smartDelete));
         } else {
             if (setSelectionToDragCaret(innerFrame, dragCaret, range, point))
@@ -636,7 +636,7 @@ static IntPoint dragLocForDHTMLDrag(const IntPoint& mouseDraggedPoint, const Int
 
 static IntPoint dragLocForSelectionDrag(Frame* src)
 {
-    IntRect draggingRect = enclosingIntRect(src->selectionBounds());
+    IntRect draggingRect = enclosingIntRect(src->selection()->bounds());
     int xpos = draggingRect.right();
     xpos = draggingRect.x() < xpos ? draggingRect.x() : xpos;
     int ypos = draggingRect.bottom();
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index bc57b4c..b31ae71 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -263,7 +263,7 @@ void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestRe
                 newSelection.appendTrailingWhitespace();            
         }
         
-        if (m_frame->shouldChangeSelection(newSelection))
+        if (m_frame->selection()->shouldChangeSelection(newSelection))
             m_frame->selection()->setSelection(newSelection, granularity, MakeNonDirectionalSelection);
     }
 }
@@ -288,7 +288,7 @@ void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHit
             m_beganSelectingText = true;
         }
 
-        if (m_frame->shouldChangeSelection(newSelection))
+        if (m_frame->selection()->shouldChangeSelection(newSelection))
             m_frame->selection()->setSelection(newSelection, granularity, MakeNonDirectionalSelection);
     }
 }
@@ -333,7 +333,7 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR
         m_beganSelectingText = true;
     }
     
-    if (m_frame->shouldChangeSelection(newSelection))
+    if (m_frame->selection()->shouldChangeSelection(newSelection))
         m_frame->selection()->setSelection(newSelection, granularity, MakeNonDirectionalSelection);
 
     return true;
@@ -391,16 +391,16 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
             newSelection.setExtent(pos);
         }
 
-        if (m_frame->selectionGranularity() != CharacterGranularity) {
-            granularity = m_frame->selectionGranularity();
-            newSelection.expandUsingGranularity(m_frame->selectionGranularity());
+        if (m_frame->selection()->granularity() != CharacterGranularity) {
+            granularity = m_frame->selection()->granularity();
+            newSelection.expandUsingGranularity(m_frame->selection()->granularity());
         }
 
         m_beganSelectingText = true;
     } else
         newSelection = VisibleSelection(visiblePos);
     
-    if (m_frame->shouldChangeSelection(newSelection))
+    if (m_frame->selection()->shouldChangeSelection(newSelection))
         m_frame->selection()->setSelection(newSelection, granularity, MakeNonDirectionalSelection);
 
     return true;
@@ -633,12 +633,12 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint&
     }
 
     newSelection.setExtent(targetPosition);
-    if (m_frame->selectionGranularity() != CharacterGranularity)
-        newSelection.expandUsingGranularity(m_frame->selectionGranularity());
+    if (m_frame->selection()->granularity() != CharacterGranularity)
+        newSelection.expandUsingGranularity(m_frame->selection()->granularity());
 
-    if (m_frame->shouldChangeSelection(newSelection)) {
+    if (m_frame->selection()->shouldChangeSelection(newSelection)) {
         m_frame->selection()->setIsDirectional(false);
-        m_frame->selection()->setSelection(newSelection, m_frame->selectionGranularity(), MakeNonDirectionalSelection);
+        m_frame->selection()->setSelection(newSelection, m_frame->selection()->granularity(), MakeNonDirectionalSelection);
     }
 }
 #endif // ENABLE(DRAG_SUPPORT)
@@ -700,13 +700,13 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
             VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint());
             newSelection = VisibleSelection(pos);
         }
-        if (m_frame->shouldChangeSelection(newSelection))
+        if (m_frame->selection()->shouldChangeSelection(newSelection))
             m_frame->selection()->setSelection(newSelection);
 
         handled = true;
     }
 
-    m_frame->notifyRendererOfSelectionChange(true);
+    m_frame->selection()->notifyRendererOfSelectionChange(true);
 
     m_frame->selection()->selectFrameElementInParentIfFullySelected();
 
diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp
index aeb4fa0..1ac50cb 100644
--- a/WebCore/page/FocusController.cpp
+++ b/WebCore/page/FocusController.cpp
@@ -278,7 +278,7 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, Keyb
 
     if (caretBrowsing) {
         VisibleSelection newSelection(Position(node, 0), Position(node, 0), DOWNSTREAM);
-        if (frame->shouldChangeSelection(newSelection))
+        if (frame->selection()->shouldChangeSelection(newSelection))
             frame->selection()->setSelection(newSelection);
     }
 
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index 8c546ce..fab0114 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -286,16 +286,6 @@ Settings* Frame::settings() const
     return m_page ? m_page->settings() : 0;
 }
 
-TextGranularity Frame::selectionGranularity() const
-{
-    return m_selectionController.granularity();
-}
-
-SelectionController* Frame::dragCaretController() const
-{
-    return m_page->dragCaretController();
-}
-
 static RegularExpression* createRegExpForLabels(const Vector<String>& labels)
 {
     // REVIEW- version of this call in FrameMac.mm caches based on the NSArray ptrs being
@@ -483,87 +473,6 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e
     return matchLabelsAgainstString(labels, element->getAttribute(idAttr));
 }
 
-void Frame::notifyRendererOfSelectionChange(bool userTriggered)
-{
-    RenderObject* renderer = 0;
-
-    document()->updateStyleIfNeeded();
-
-    if (selection()->rootEditableElement())
-        renderer = selection()->rootEditableElement()->shadowAncestorNode()->renderer();
-
-    // If the current selection is in a textfield or textarea, notify the renderer that the selection has changed
-    if (renderer && renderer->isTextControl())
-        toRenderTextControl(renderer)->selectionChanged(userTriggered);
-}
-
-// Helper function that tells whether a particular node is an element that has an entire
-// Frame and FrameView, a <frame>, <iframe>, or <object>.
-static bool isFrameElement(const Node *n)
-{
-    if (!n)
-        return false;
-    RenderObject *renderer = n->renderer();
-    if (!renderer || !renderer->isWidget())
-        return false;
-    Widget* widget = toRenderWidget(renderer)->widget();
-    return widget && widget->isFrameView();
-}
-
-void Frame::setFocusedNodeIfNeeded()
-{
-    if (selection()->isNone() || !selection()->isFocused())
-        return;
-
-    bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
-    if (caretBrowsing) {
-        Node* anchor = enclosingAnchorElement(selection()->base());
-        if (anchor) {
-            page()->focusController()->setFocusedNode(anchor, this);
-            return;
-        }
-    }
-
-    Node* target = selection()->rootEditableElement();
-    if (target) {
-        RenderObject* renderer = target->renderer();
-
-        // Walk up the render tree to search for a node to focus.
-        // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
-        while (renderer) {
-            // We don't want to set focus on a subframe when selecting in a parent frame,
-            // so add the !isFrameElement check here. There's probably a better way to make this
-            // work in the long term, but this is the safest fix at this time.
-            if (target && target->isMouseFocusable() && !isFrameElement(target)) {
-                page()->focusController()->setFocusedNode(target, this);
-                return;
-            }
-            renderer = renderer->parent();
-            if (renderer)
-                target = renderer->node();
-        }
-        document()->setFocusedNode(0);
-    }
-
-    if (caretBrowsing)
-        page()->focusController()->setFocusedNode(0, this);
-}
-
-void Frame::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
-{
-#if ENABLE(TEXT_CARET)
-    SelectionController* dragCaretController = m_page->dragCaretController();
-    ASSERT(dragCaretController->selection().isCaret());
-    if (dragCaretController->selection().start().node()->document()->frame() == this)
-        dragCaretController->paintCaret(p, tx, ty, clipRect);
-#else
-    UNUSED_PARAM(p);
-    UNUSED_PARAM(tx);
-    UNUSED_PARAM(ty);
-    UNUSED_PARAM(clipRect);
-#endif
-}
-
 void Frame::setPrinting(bool printing, const FloatSize& pageSize, float maximumShrinkRatio, AdjustViewSizeOrNot shouldAdjustViewSize)
 {
     m_doc->setPrinting(printing);
@@ -611,11 +520,6 @@ void Frame::injectUserScriptsForWorld(DOMWrapperWorld* world, const UserScriptVe
     }
 }
 
-bool Frame::shouldDeleteSelection(const VisibleSelection& selection) const
-{
-    return editor()->client()->shouldDeleteRange(selection.toNormalizedRange().get());
-}
-
 bool Frame::isContentEditable() const
 {
     if (m_editor.clientIsEditable())
@@ -623,11 +527,6 @@ bool Frame::isContentEditable() const
     return m_doc->inDesignMode();
 }
 
-void Frame::setTypingStyle(CSSMutableStyleDeclaration *style)
-{
-    m_typingStyle = style;
-}
-
 #ifndef NDEBUG
 static HashSet<Frame*>& keepAliveSet()
 {
@@ -706,123 +605,6 @@ RenderPart* Frame::ownerRenderer() const
     return toRenderPart(object);
 }
 
-// returns FloatRect because going through IntRect would truncate any floats
-FloatRect Frame::selectionBounds(bool clipToVisibleContent) const
-{
-    RenderView* root = contentRenderer();
-    FrameView* view = m_view.get();
-    if (!root || !view)
-        return IntRect();
-
-    IntRect selectionRect = root->selectionBounds(clipToVisibleContent);
-    return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
-}
-
-void Frame::selectionTextRects(Vector<FloatRect>& rects, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent) const
-{
-    RenderView* root = contentRenderer();
-    if (!root)
-        return;
-
-    RefPtr<Range> selectedRange = selection()->toNormalizedRange();
-
-    FloatRect visibleContentRect = m_view->visibleContentRect();
-    
-    // FIMXE: we are appending empty rects to the list for those that fall outside visibleContentRect.
-    // We may not want to do that.
-    if (respectTransforms) {
-        Vector<FloatQuad> quads;
-        selectedRange->textQuads(quads, true);
-
-        unsigned size = quads.size();
-        for (unsigned i = 0; i < size; ++i) {
-            IntRect currRect = quads[i].enclosingBoundingBox();
-            if (clipToVisibleContent)
-                rects.append(intersection(currRect, visibleContentRect));
-            else
-                rects.append(currRect);
-        }
-    } else {
-        Vector<IntRect> intRects;
-        selectedRange->textRects(intRects, true);
-
-        unsigned size = intRects.size();
-        for (unsigned i = 0; i < size; ++i) {
-            if (clipToVisibleContent)
-                rects.append(intersection(intRects[i], visibleContentRect));
-            else
-                rects.append(intRects[i]);
-        }
-    }
-}
-
-// Scans logically forward from "start", including any child frames
-static HTMLFormElement *scanForForm(Node *start)
-{
-    Node *n;
-    for (n = start; n; n = n->traverseNextNode()) {
-        if (n->hasTagName(formTag))
-            return static_cast<HTMLFormElement*>(n);
-        else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())
-            return static_cast<HTMLFormControlElement*>(n)->form();
-        else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {
-            Node *childDoc = static_cast<HTMLFrameElementBase*>(n)->contentDocument();
-            if (HTMLFormElement *frameResult = scanForForm(childDoc))
-                return frameResult;
-        }
-    }
-    return 0;
-}
-
-// We look for either the form containing the current focus, or for one immediately after it
-HTMLFormElement *Frame::currentForm() const
-{
-    // start looking either at the active (first responder) node, or where the selection is
-    Node *start = m_doc ? m_doc->focusedNode() : 0;
-    if (!start)
-        start = selection()->start().node();
-
-    // try walking up the node tree to find a form element
-    Node *n;
-    for (n = start; n; n = n->parentNode()) {
-        if (n->hasTagName(formTag))
-            return static_cast<HTMLFormElement*>(n);
-        else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())
-            return static_cast<HTMLFormControlElement*>(n)->form();
-    }
-
-    // try walking forward in the node tree to find a form element
-    return start ? scanForForm(start) : 0;
-}
-
-void Frame::revealSelection(const ScrollAlignment& alignment, bool revealExtent)
-{
-    IntRect rect;
-
-    switch (selection()->selectionType()) {
-    case VisibleSelection::NoSelection:
-        return;
-    case VisibleSelection::CaretSelection:
-        rect = selection()->absoluteCaretBounds();
-        break;
-    case VisibleSelection::RangeSelection:
-        rect = revealExtent ? VisiblePosition(selection()->extent()).absoluteCaretBounds() : enclosingIntRect(selectionBounds(false));
-        break;
-    }
-
-    Position start = selection()->start();
-    ASSERT(start.node());
-    if (start.node() && start.node()->renderer()) {
-        // FIXME: This code only handles scrolling the startContainer's layer, but
-        // the selection rect could intersect more than just that.
-        // See <rdar://problem/4799899>.
-        if (RenderLayer* layer = start.node()->renderer()->enclosingLayer()) {
-            layer->scrollRectToVisible(rect, false, alignment, alignment);
-            selection()->updateAppearance();
-        }
-    }
-}
-
 Frame* Frame::frameForWidget(const Widget* widget)
 {
     ASSERT_ARG(widget, widget);
@@ -853,22 +635,6 @@ void Frame::clearTimers()
     clearTimers(m_view.get(), document());
 }
 
-void Frame::setSelectionFromNone()
-{
-    // Put a caret inside the body if the entire frame is editable (either the
-    // entire WebView is editable or designMode is on for this document).
-    Document *doc = document();
-    bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
-    if (!selection()->isNone() || !(isContentEditable() || caretBrowsing))
-        return;
-
-    Node* node = doc->documentElement();
-    while (node && !node->hasTagName(bodyTag))
-        node = node->traverseNextNode();
-    if (node)
-        selection()->setSelection(VisibleSelection(Position(node, 0), DOWNSTREAM));
-}
-
 void Frame::setDOMWindow(DOMWindow* domWindow)
 {
     if (m_domWindow) {
@@ -979,11 +745,6 @@ String Frame::documentTypeString() const
     return String();
 }
 
-bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const
-{
-    return editor()->shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false);
-}
-
 VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
 {
     HitTestResult result = eventHandler()->hitTestResultAtPoint(framePoint, true);
diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h
index 1e6b9b6..6c5281b 100644
--- a/WebCore/page/Frame.h
+++ b/WebCore/page/Frame.h
@@ -29,14 +29,12 @@
 #define Frame_h
 
 #include "AnimationController.h"
-#include "CSSMutableStyleDeclaration.h"
 #include "DragImage.h"
 #include "Editor.h"
 #include "EventHandler.h"
 #include "FrameLoader.h"
 #include "FrameTree.h"
 #include "ScriptController.h"
-#include "ScrollBehavior.h"
 #include "UserScriptTypes.h"
 #include "ZoomMode.h"
 
@@ -67,38 +65,32 @@ namespace WebCore {
     class RenderPart;
     class TiledBackingStore;
 
-    class Frame : public RefCounted<Frame>
-#if ENABLE(TILED_BACKING_STORE)
-        , public TiledBackingStoreClient
+#if !ENABLE(TILED_BACKING_STORE)
+    class TiledBackingStoreClient { };
 #endif
-    {
+
+    class Frame : public RefCounted<Frame>, public TiledBackingStoreClient {
     public:
         static PassRefPtr<Frame> create(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
-        void setView(PassRefPtr<FrameView>);
-        ~Frame();
 
         void init();
+        void setView(PassRefPtr<FrameView>);
+        void createView(const IntSize&, const Color&, bool, const IntSize&, bool,
+            ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,
+            ScrollbarMode = ScrollbarAuto, bool verticalLock = false);
 
-        Page* page() const;
-        void detachFromPage();
-        void transferChildFrameToNewDocument();
-
-        HTMLFrameOwnerElement* ownerElement() const;
+        ~Frame();
 
+        void detachFromPage();
         void pageDestroyed();
         void disconnectOwnerElement();
 
+        Page* page() const;
+        HTMLFrameOwnerElement* ownerElement() const;
+
         Document* document() const;
         FrameView* view() const;
 
-        void setDOMWindow(DOMWindow*);
-        void clearFormerDOMWindow(DOMWindow*);
-
-        // Unlike many of the accessors in Frame, domWindow() always creates a new DOMWindow if m_domWindow is null.
-        // Callers that don't need a new DOMWindow to be created should use existingDOMWindow().
-        DOMWindow* domWindow() const;
-        DOMWindow* existingDOMWindow() { return m_domWindow.get(); }
-
         Editor* editor() const;
         EventHandler* eventHandler() const;
         FrameLoader* loader() const;
@@ -108,31 +100,30 @@ namespace WebCore {
         AnimationController* animation() const;
         ScriptController* script();
 
-        RenderView* contentRenderer() const; // root renderer for the document contained in this frame
-        RenderPart* ownerRenderer() const; // renderer for the element that contains this frame
+        RenderView* contentRenderer() const; // Root of the render tree for the document contained in this frame.
+        RenderPart* ownerRenderer() const; // Renderer for the element that contains this frame.
+
+        void transferChildFrameToNewDocument();
+
+    // ======== All public functions below this point are candidates to move out of Frame into another class. ========
 
         bool isDisconnected() const;
         void setIsDisconnected(bool);
         bool excludeFromTextSearch() const;
         void setExcludeFromTextSearch(bool);
 
-        void createView(const IntSize&, const Color&, bool, const IntSize &, bool,
-                        ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,
-                        ScrollbarMode = ScrollbarAuto, bool verticalLock = false);
-
         void injectUserScripts(UserScriptInjectionTime);
         
         String layerTreeAsText() const;
 
-    private:
-        void injectUserScriptsForWorld(DOMWrapperWorld*, const UserScriptVector&, UserScriptInjectionTime);
-
-    private:
-        Frame(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
-
-    // === undecided, would like to consider moving to another class
+        // Unlike most accessors in this class, domWindow() always creates a new DOMWindow if m_domWindow is null.
+        // Callers that don't need a new DOMWindow to be created should use existingDOMWindow().
+        DOMWindow* domWindow() const;
+        DOMWindow* existingDOMWindow() { return m_domWindow.get(); }
+        void setDOMWindow(DOMWindow*);
+        void clearFormerDOMWindow(DOMWindow*);
+        void clearDOMWindow();
 
-    public:
         static Frame* frameForWidget(const Widget*);
 
         Settings* settings() const; // can be NULL
@@ -163,80 +154,25 @@ namespace WebCore {
 
         String documentTypeString() const;
 
-        // This method -- and the corresponding list of former DOM windows --
-        // should move onto ScriptController
-        void clearDOMWindow();
-
         String displayStringModifiedByEncoding(const String& str) const
         {
             return document() ? document()->displayStringModifiedByEncoding(str) : str;
         }
 
-#if ENABLE(TILED_BACKING_STORE)
-        // FIXME: This should be in FrameView, not Frame.
-        TiledBackingStore* tiledBackingStore() const { return m_tiledBackingStore.get(); }
-        void setTiledBackingStoreEnabled(bool);
-#endif
-
         DragImageRef nodeImage(Node*);
         DragImageRef dragImageForSelection();
 
-    private:
-        void lifeSupportTimerFired(Timer<Frame>*);
-
-    // === to be moved into SelectionController
-
-    public:
-        TextGranularity selectionGranularity() const;
-
-        bool shouldChangeSelection(const VisibleSelection&) const;
-        bool shouldDeleteSelection(const VisibleSelection&) const;
-        void setFocusedNodeIfNeeded();
-        void notifyRendererOfSelectionChange(bool userTriggered);
-
-        void paintDragCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const;
-
         bool isContentEditable() const; // if true, everything in frame is editable
 
-        CSSMutableStyleDeclaration* typingStyle() const;
-        void setTypingStyle(CSSMutableStyleDeclaration*);
-        void clearTypingStyle();
-
-        FloatRect selectionBounds(bool clipToVisibleContent = true) const;
-        enum SelectionRectRespectTransforms { RespectTransforms = true, IgnoreTransforms = false };
-        void selectionTextRects(Vector<FloatRect>&, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent = true) const;
-
-        HTMLFormElement* currentForm() const;
-
-        void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, bool revealExtent = false);
-        void setSelectionFromNone();
-
-        SelectionController* dragCaretController() const;
+        VisiblePosition visiblePositionForPoint(const IntPoint& framePoint);
+        Document* documentAtPoint(const IntPoint& windowPoint);
 
         String searchForLabelsAboveCell(RegularExpression*, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell);
         String searchForLabelsBeforeElement(const Vector<String>& labels, Element*, size_t* resultDistance, bool* resultIsInCellAbove);
         String matchLabelsAgainstElement(const Vector<String>& labels, Element*);
 
-        VisiblePosition visiblePositionForPoint(const IntPoint& framePoint);
-        Document* documentAtPoint(const IntPoint& windowPoint);
-
-#if ENABLE(TILED_BACKING_STORE)
-        // FIXME: This should be in FrameView, not Frame.
-
-    private:
-        // TiledBackingStoreClient interface
-        virtual void tiledBackingStorePaintBegin();
-        virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&);
-        virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea);
-        virtual IntRect tiledBackingStoreContentsRect();
-        virtual IntRect tiledBackingStoreVisibleRect();
-#endif
-
 #if PLATFORM(MAC)
 
-    // === undecided, would like to consider moving to another class
-
-    public:
         NSString* searchForNSLabelsAboveCell(RegularExpression*, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell);
         NSString* searchForLabelsBeforeElement(NSArray* labels, Element*, size_t* resultDistance, bool* resultIsInCellAbove);
         NSString* matchLabelsAgainstElement(NSArray* labels, Element*);
@@ -251,7 +187,14 @@ namespace WebCore {
 
 #endif
 
+    // ========
+
     private:
+        Frame(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
+
+        void injectUserScriptsForWorld(DOMWrapperWorld*, const UserScriptVector&, UserScriptInjectionTime);
+        void lifeSupportTimerFired(Timer<Frame>*);
+
         Page* m_page;
         mutable FrameTree m_treeNode;
         mutable FrameLoader m_loader;
@@ -271,8 +214,6 @@ namespace WebCore {
         mutable EventHandler m_eventHandler;
         mutable AnimationController m_animationController;
 
-        RefPtr<CSSMutableStyleDeclaration> m_typingStyle;
-
         Timer<Frame> m_lifeSupportTimer;
 
 #if ENABLE(ORIENTATION_EVENTS)
@@ -283,7 +224,21 @@ namespace WebCore {
         bool m_isDisconnected;
         bool m_excludeFromTextSearch;
 
-#if ENABLE(TILED_BACKING_STORE)        
+#if ENABLE(TILED_BACKING_STORE)
+    // FIXME: The tiled backing store belongs in FrameView, not Frame.
+
+    public:
+        TiledBackingStore* tiledBackingStore() const { return m_tiledBackingStore.get(); }
+        void setTiledBackingStoreEnabled(bool);
+
+    private:
+        // TiledBackingStoreClient interface
+        virtual void tiledBackingStorePaintBegin();
+        virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&);
+        virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea);
+        virtual IntRect tiledBackingStoreContentsRect();
+        virtual IntRect tiledBackingStoreVisibleRect();
+
         OwnPtr<TiledBackingStore> m_tiledBackingStore;
 #endif
     };
@@ -333,16 +288,6 @@ namespace WebCore {
         return &m_animationController;
     }
 
-    inline CSSMutableStyleDeclaration* Frame::typingStyle() const
-    {
-        return m_typingStyle.get();
-    }
-
-    inline void Frame::clearTypingStyle()
-    {
-        m_typingStyle = 0;
-    }
-
     inline HTMLFrameOwnerElement* Frame::ownerElement() const
     {
         return m_ownerElement;
diff --git a/WebCore/page/chromium/EventHandlerChromium.cpp b/WebCore/page/chromium/EventHandlerChromium.cpp
index 719163f..dd6cf99 100644
--- a/WebCore/page/chromium/EventHandlerChromium.cpp
+++ b/WebCore/page/chromium/EventHandlerChromium.cpp
@@ -63,7 +63,7 @@ bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m
         VisiblePosition visiblePos(
             mev.targetNode()->renderer()->positionForPoint(mev.localPoint()));
         VisibleSelection newSelection(visiblePos);
-        if (m_frame->shouldChangeSelection(newSelection))
+        if (m_frame->selection()->shouldChangeSelection(newSelection))
             m_frame->selection()->setSelection(newSelection);
     }
 
diff --git a/WebCore/page/chromium/FrameChromium.cpp b/WebCore/page/chromium/FrameChromium.cpp
index 4146b39..b9097d0 100644
--- a/WebCore/page/chromium/FrameChromium.cpp
+++ b/WebCore/page/chromium/FrameChromium.cpp
@@ -101,7 +101,7 @@ DragImageRef Frame::dragImageForSelection()
     m_view->setPaintBehavior(PaintBehaviorSelectionOnly);
     m_doc->updateLayout();
 
-    IntRect paintingRect = enclosingIntRect(selectionBounds());
+    IntRect paintingRect = enclosingIntRect(selection()->bounds());
 
     OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size()));
     if (!buffer)
diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm
index 510cb96..8397776 100644
--- a/WebCore/page/mac/FrameMac.mm
+++ b/WebCore/page/mac/FrameMac.mm
@@ -347,7 +347,7 @@ NSImage* Frame::selectionImage(bool forceBlackText) const
 {
     m_view->setPaintBehavior(PaintBehaviorSelectionOnly | (forceBlackText ? PaintBehaviorForceBlackText : 0));
     m_doc->updateLayout();
-    NSImage* result = imageFromRect(selectionBounds());
+    NSImage* result = imageFromRect(selection()->bounds());
     m_view->setPaintBehavior(PaintBehaviorNormal);
     return result;
 }
diff --git a/WebCore/page/win/FrameCGWin.cpp b/WebCore/page/win/FrameCGWin.cpp
index b61deef..62d33ef 100644
--- a/WebCore/page/win/FrameCGWin.cpp
+++ b/WebCore/page/win/FrameCGWin.cpp
@@ -87,7 +87,7 @@ HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
     frame->document()->updateLayout();
 
     frame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | (forceBlackText ? PaintBehaviorForceBlackText : 0));
-    FloatRect fr = frame->selectionBounds();
+    FloatRect fr = frame->selection()->bounds();
     IntRect ir(static_cast<int>(fr.x()), static_cast<int>(fr.y()),
                static_cast<int>(fr.width()), static_cast<int>(fr.height()));
     HBITMAP image = imageFromRect(frame, ir);
diff --git a/WebCore/page/wince/FrameWince.cpp b/WebCore/page/wince/FrameWince.cpp
index 7cfbae0..ba51cb6 100644
--- a/WebCore/page/wince/FrameWince.cpp
+++ b/WebCore/page/wince/FrameWince.cpp
@@ -110,7 +110,7 @@ HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
         return 0;
 
     frame->view()->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
-    FloatRect fr = frame->selectionBounds();
+    FloatRect fr = frame->selection()->bounds();
     IntRect ir((int)fr.x(), (int)fr.y(), (int)fr.width(), (int)fr.height());
     if (ir.isEmpty())
         return 0;
diff --git a/WebCore/platform/mac/ClipboardMac.mm b/WebCore/platform/mac/ClipboardMac.mm
index bdd190e..74a93b6 100644
--- a/WebCore/platform/mac/ClipboardMac.mm
+++ b/WebCore/platform/mac/ClipboardMac.mm
@@ -372,7 +372,7 @@ void ClipboardMac::writeRange(Range* range, Frame* frame)
 {
     ASSERT(range);
     ASSERT(frame);
-    Pasteboard::writeSelection(m_pasteboard.get(), range, frame->editor()->smartInsertDeleteEnabled() && frame->selectionGranularity() == WordGranularity, frame);
+    Pasteboard::writeSelection(m_pasteboard.get(), range, frame->editor()->smartInsertDeleteEnabled() && frame->selection()->granularity() == WordGranularity, frame);
 }
 
 void ClipboardMac::writePlainText(const String& text)
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 66299ab..7f18bf0 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -2140,7 +2140,7 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
 
 void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
 {
-    SelectionController* selection = type == CursorCaret ? frame()->selection() : frame()->dragCaretController();
+    SelectionController* selection = type == CursorCaret ? frame()->selection() : frame()->page()->dragCaretController();
 
     // Paint the caret if the SelectionController says so or if caret browsing is enabled
     bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
@@ -2153,7 +2153,7 @@ void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType typ
         if (type == CursorCaret)
             frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
         else
-            frame()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
+            frame()->selection()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
     }
 }
 
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index b9b1ae0..ee87a50 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,14 @@
+2010-09-09  Darin Adler  <darin at apple.com>
+
+        Reviewed by Adam Barth.
+
+        Move functions from Frame to SelectionController as planned
+        https://bugs.webkit.org/show_bug.cgi?id=45508
+
+        * src/WebFrameImpl.cpp:
+        (WebKit::WebFrameImpl::selectionBoundsRect):
+        Call functions on selection().
+
 2010-09-10  Adam Barth  <abarth at webkit.org>
 
         Chromium build fix (one hopes!)
diff --git a/WebKit/chromium/src/WebFrameImpl.cpp b/WebKit/chromium/src/WebFrameImpl.cpp
index e622d99..baa00d5 100644
--- a/WebKit/chromium/src/WebFrameImpl.cpp
+++ b/WebKit/chromium/src/WebFrameImpl.cpp
@@ -1712,7 +1712,7 @@ int WebFrameImpl::pageNumberForElementById(const WebString& id,
 WebRect WebFrameImpl::selectionBoundsRect() const
 {
     if (hasSelection())
-        return IntRect(frame()->selectionBounds(false));
+        return IntRect(frame()->selection()->bounds(false));
 
     return WebRect();
 }
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index bfe87fe..c786a02 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,29 @@
+2010-09-09  Darin Adler  <darin at apple.com>
+
+        Reviewed by Adam Barth.
+
+        Move functions from Frame to SelectionController as planned
+        https://bugs.webkit.org/show_bug.cgi?id=45508
+
+        * WebView/WebFrame.mm:
+        (-[WebFrame _selectionGranularity]):
+        (-[WebFrame _insertParagraphSeparatorInQuotedContent]):
+        (-[WebFrame _typingStyle]):
+        (-[WebFrame _replaceSelectionWithFragment:selectReplacement:smartReplace:matchStyle:]):
+        * WebView/WebHTMLRepresentation.mm:
+        (-[WebHTMLRepresentation currentForm]):
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView jumpToSelection:]):
+        (-[WebHTMLView centerSelectionInVisibleArea:]):
+        (-[WebHTMLView _canSmartCopyOrDelete]):
+        (-[WebHTMLView _lookUpInDictionaryFromMenu:]):
+        (-[WebHTMLView selectionRect]):
+        (-[WebHTMLView selectionTextRects]):
+        (-[WebHTMLView selectionImageRect]):
+        * WebView/WebView.mm:
+        (-[WebView setEditable:]):
+        Call functions on selection().
+
 2010-09-10  Adam Barth  <abarth at webkit.org>
 
         Reviewed by Eric Seidel.
diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm
index 9a987be..6aa8f00 100644
--- a/WebKit/mac/WebView/WebFrame.mm
+++ b/WebKit/mac/WebView/WebFrame.mm
@@ -708,7 +708,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
 
 - (TextGranularity)_selectionGranularity
 {
-    return _private->coreFrame->selectionGranularity();
+    return _private->coreFrame->selection()->granularity();
 }
 
 - (NSRange)_convertToNSRange:(Range *)range
@@ -852,7 +852,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
         return;
     
     TypingCommand::insertParagraphSeparatorInQuotedContent(_private->coreFrame->document());
-    _private->coreFrame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
+    _private->coreFrame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
 }
 
 - (VisiblePosition)_visiblePositionForPoint:(NSPoint)point
@@ -888,9 +888,9 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
 
 - (DOMCSSStyleDeclaration *)_typingStyle
 {
-    if (!_private->coreFrame || !_private->coreFrame->typingStyle())
+    if (!_private->coreFrame || !_private->coreFrame->selection()->typingStyle())
         return nil;
-    return kit(_private->coreFrame->typingStyle()->copy().get());
+    return kit(_private->coreFrame->selection()->typingStyle()->copy().get());
 }
 
 - (void)_setTypingStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(EditAction)undoAction
@@ -1160,7 +1160,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
         return;
     
     applyCommand(ReplaceSelectionCommand::create(_private->coreFrame->document(), core(fragment), selectReplacement, smartReplace, matchStyle));
-    _private->coreFrame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
+    _private->coreFrame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
 }
 
 - (void)_replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
diff --git a/WebKit/mac/WebView/WebHTMLRepresentation.mm b/WebKit/mac/WebView/WebHTMLRepresentation.mm
index 188747d..2c37734 100644
--- a/WebKit/mac/WebView/WebHTMLRepresentation.mm
+++ b/WebKit/mac/WebView/WebHTMLRepresentation.mm
@@ -323,7 +323,7 @@ static HTMLInputElement* inputElementFromDOMElement(DOMElement* element)
 
 - (DOMElement *)currentForm
 {
-    return kit(core([_private->dataSource webFrame])->currentForm());
+    return kit(core([_private->dataSource webFrame])->selection()->currentForm());
 }
 
 - (NSArray *)controlsInForm:(DOMElement *)form
diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm
index bd71eff..65b266a 100644
--- a/WebKit/mac/WebView/WebHTMLView.mm
+++ b/WebKit/mac/WebView/WebHTMLView.mm
@@ -1914,12 +1914,11 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
 
 - (NSImage *)_selectionDraggingImage
 {
-    if ([self _hasSelection]) {
-        NSImage *dragImage = core([self _frame])->selectionImage();
-        [dragImage _web_dissolveToFraction:WebDragImageAlpha];
-        return dragImage;
-    }
-    return nil;
+    if (![self _hasSelection])
+        return nil;
+    NSImage *dragImage = core([self _frame])->selectionImage();
+    [dragImage _web_dissolveToFraction:WebDragImageAlpha];
+    return dragImage;
 }
 
 - (NSRect)_selectionDraggingRect
@@ -2664,7 +2663,7 @@ WEBCORE_COMMAND(yankAndSelect)
     COMMAND_PROLOGUE
 
     if (Frame* coreFrame = core([self _frame]))
-        coreFrame->revealSelection(ScrollAlignment::alignCenterAlways);
+        coreFrame->selection()->revealSelection(ScrollAlignment::alignCenterAlways);
 }
 
 - (NSCellStateValue)selectionHasStyle:(CSSStyleDeclaration*)style
@@ -4197,7 +4196,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
     COMMAND_PROLOGUE
 
     if (Frame* coreFrame = core([self _frame]))
-        coreFrame->revealSelection(ScrollAlignment::alignCenterAlways);
+        coreFrame->selection()->revealSelection(ScrollAlignment::alignCenterAlways);
 }
 
 - (NSData *)_selectionStartFontAttributesAsRTF
@@ -5145,7 +5144,7 @@ static BOOL writingDirectionKeyBindingsEnabled()
     if (![[self _webView] smartInsertDeleteEnabled])
         return NO;
     Frame* coreFrame = core([self _frame]);
-    return coreFrame && coreFrame->selectionGranularity() == WordGranularity;
+    return coreFrame && coreFrame->selection()->granularity() == WordGranularity;
 }
 
 - (NSEvent *)_mouseDownEvent
@@ -5360,7 +5359,7 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
     if (!coreFrame)
         return;
 
-    NSRect rect = coreFrame->selectionBounds();
+    NSRect rect = coreFrame->selection()->bounds();
 
 #ifndef BUILDING_ON_TIGER
     NSDictionary *attributes = [attrString fontAttributesInRange:NSMakeRange(0,1)];
@@ -6037,25 +6036,27 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
 
 - (NSRect)selectionRect
 {
-    if ([self _hasSelection])
-        return core([self _frame])->selectionBounds();
-    return NSZeroRect;
+    if (![self _hasSelection])
+        return NSZeroRect;
+    return core([self _frame])->selection()->bounds();
 }
 
 - (NSArray *)selectionTextRects
 {
     if (![self _hasSelection])
         return nil;
-    
+
     Vector<FloatRect> list;
     if (Frame* coreFrame = core([self _frame]))
-        coreFrame->selectionTextRects(list, Frame::RespectTransforms);
+        coreFrame->selection()->getClippedVisibleTextRectangles(list);
 
-    unsigned size = list.size();
-    NSMutableArray *result = [[[NSMutableArray alloc] initWithCapacity:size] autorelease];
-    for (unsigned i = 0; i < size; ++i)
+    size_t size = list.size();
+
+    NSMutableArray *result = [NSMutableArray arrayWithCapacity:size];
+
+    for (size_t i = 0; i < size; ++i)
         [result addObject:[NSValue valueWithRect:list[i]]];
-    
+
     return result;
 }
 
@@ -6066,16 +6067,16 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
 
 - (NSImage *)selectionImageForcingBlackText:(BOOL)forceBlackText
 {
-    if ([self _hasSelection])
-        return core([self _frame])->selectionImage(forceBlackText);
-    return nil;
+    if (![self _hasSelection])
+        return nil;
+    return core([self _frame])->selectionImage(forceBlackText);
 }
 
 - (NSRect)selectionImageRect
 {
-    if ([self _hasSelection])
-        return core([self _frame])->selectionBounds();
-    return NSZeroRect;
+    if (![self _hasSelection])
+        return NSZeroRect;
+    return core([self _frame])->selection()->bounds();
 }
 
 - (NSArray *)pasteboardTypesForSelection
diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm
index 0125e1c..b6fbcd5 100644
--- a/WebKit/mac/WebView/WebView.mm
+++ b/WebKit/mac/WebView/WebView.mm
@@ -4769,7 +4769,7 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue jsValu
                 mainFrame->editor()->applyEditingStyleToBodyElement();
                 // If the WebView is made editable and the selection is empty, set it to something.
                 if (![self selectedDOMRange])
-                    mainFrame->setSelectionFromNone();
+                    mainFrame->selection()->setSelectionFromNone();
             }
         }
     }
diff --git a/WebKit/win/ChangeLog b/WebKit/win/ChangeLog
index bfa9ccc..e45ecde 100644
--- a/WebKit/win/ChangeLog
+++ b/WebKit/win/ChangeLog
@@ -1,3 +1,15 @@
+2010-09-09  Darin Adler  <darin at apple.com>
+
+        Reviewed by Adam Barth.
+
+        Move functions from Frame to SelectionController as planned
+        https://bugs.webkit.org/show_bug.cgi?id=45508
+
+        * WebView.cpp:
+        (WebView::selectionRect):
+        (WebView::centerSelectionInVisibleArea):
+        Call functions on selection().
+
 2010-09-10  Adam Barth  <abarth at webkit.org>
 
         Reviewed by Eric Seidel.
diff --git a/WebKit/win/WebView.cpp b/WebKit/win/WebView.cpp
index 0a1e334..bec6483 100644
--- a/WebKit/win/WebView.cpp
+++ b/WebKit/win/WebView.cpp
@@ -3401,7 +3401,7 @@ HRESULT STDMETHODCALLTYPE WebView::selectionRect(RECT* rc)
     WebCore::Frame* frame = m_page->focusController()->focusedOrMainFrame();
 
     if (frame) {
-        IntRect ir = enclosingIntRect(frame->selectionBounds());
+        IntRect ir = enclosingIntRect(frame->selection()->bounds());
         ir = frame->view()->convertToContainingWindow(ir);
         ir.move(-frame->view()->scrollOffset().width(), -frame->view()->scrollOffset().height());
         rc->left = ir.x();
@@ -3561,7 +3561,7 @@ HRESULT STDMETHODCALLTYPE WebView::centerSelectionInVisibleArea(
     if (!coreFrame)
         return E_FAIL;
 
-    coreFrame->revealSelection(ScrollAlignment::alignCenterAlways);
+    coreFrame->selection()->revealSelection(ScrollAlignment::alignCenterAlways);
     return S_OK;
 }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list