5fa2769c8691bc2b086d968f650e8c8f2879aab3
[WebKit-https.git] / WebCore / editing / SelectionController.h
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef SelectionController_h
27 #define SelectionController_h
28
29 #include "IntRect.h"
30 #include "Range.h"
31 #include "Timer.h"
32 #include "VisibleSelection.h"
33 #include <wtf/Noncopyable.h>
34
35 namespace WebCore {
36
37 class Frame;
38 class GraphicsContext;
39 class RenderObject;
40 class RenderView;
41 class Settings;
42 class VisiblePosition;
43
44 enum DirectionalityPolicy { MakeNonDirectionalSelection, MakeDirectionalSelection };
45
46 class SelectionController : public Noncopyable {
47 public:
48     enum EAlteration { AlterationMove, AlterationExtend };
49     enum EDirection { DirectionForward, DirectionBackward, DirectionRight, DirectionLeft };
50     enum CursorAlignOnScroll { AlignCursorOnScrollIfNeeded,
51                                AlignCursorOnScrollAlways };
52
53     SelectionController(Frame* = 0, bool isDragCaretController = false);
54
55     Element* rootEditableElement() const { return m_selection.rootEditableElement(); }
56     bool isContentEditable() const { return m_selection.isContentEditable(); }
57     bool isContentRichlyEditable() const { return m_selection.isContentRichlyEditable(); }
58     Node* shadowTreeRootNode() const { return m_selection.shadowTreeRootNode(); }
59      
60     void moveTo(const Range*, EAffinity, bool userTriggered = false);
61     void moveTo(const VisiblePosition&, bool userTriggered = false, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded);
62     void moveTo(const VisiblePosition&, const VisiblePosition&, bool userTriggered = false);
63     void moveTo(const Position&, EAffinity, bool userTriggered = false);
64     void moveTo(const Position&, const Position&, EAffinity, bool userTriggered = false);
65
66     const VisibleSelection& selection() const { return m_selection; }
67     void setSelection(const VisibleSelection&, bool closeTyping = true, bool clearTypingStyle = true, bool userTriggered = false, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded, TextGranularity = CharacterGranularity, DirectionalityPolicy = MakeDirectionalSelection);
68     void setSelection(const VisibleSelection& selection, TextGranularity granularity, DirectionalityPolicy directionality = MakeDirectionalSelection) { setSelection(selection, true, true, false, AlignCursorOnScrollIfNeeded, granularity, directionality); }
69     bool setSelectedRange(Range*, EAffinity, bool closeTyping);
70     void selectAll();
71     void clear();
72     
73     // Call this after doing user-triggered selections to make it easy to delete the frame you entirely selected.
74     void selectFrameElementInParentIfFullySelected();
75
76     bool contains(const IntPoint&);
77
78     VisibleSelection::SelectionType selectionType() const { return m_selection.selectionType(); }
79
80     EAffinity affinity() const { return m_selection.affinity(); }
81
82     bool modify(EAlteration, EDirection, TextGranularity, bool userTriggered = false);
83     bool modify(EAlteration, int verticalDistance, bool userTriggered = false, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded);
84     TextGranularity granularity() const { return m_granularity; }
85
86     void setStart(const VisiblePosition &, bool userTriggered = false);
87     void setEnd(const VisiblePosition &, bool userTriggered = false);
88     
89     void setBase(const VisiblePosition&, bool userTriggered = false);
90     void setBase(const Position&, EAffinity, bool userTriggered = false);
91     void setExtent(const VisiblePosition&, bool userTriggered = false);
92     void setExtent(const Position&, EAffinity, bool userTriggered = false);
93
94     Position base() const { return m_selection.base(); }
95     Position extent() const { return m_selection.extent(); }
96     Position start() const { return m_selection.start(); }
97     Position end() const { return m_selection.end(); }
98
99     // Return the renderer that is responsible for painting the caret (in the selection start node)
100     RenderObject* caretRenderer() const;
101
102     // Caret rect local to the caret's renderer
103     IntRect localCaretRect();
104     IntRect localCaretRectForPainting() const { return m_caretRect; }
105
106     // Bounds of (possibly transformed) caret in absolute coords
107     IntRect absoluteCaretBounds();
108     void setCaretRectNeedsUpdate(bool flag = true);
109
110     void setIsDirectional(bool);
111     void willBeModified(EAlteration, EDirection);
112     
113     bool isNone() const { return m_selection.isNone(); }
114     bool isCaret() const { return m_selection.isCaret(); }
115     bool isRange() const { return m_selection.isRange(); }
116     bool isCaretOrRange() const { return m_selection.isCaretOrRange(); }
117     bool isInPasswordField() const;
118     bool isAll(StayInEditableContent stayInEditableContent = MustStayInEditableContent) const { return m_selection.isAll(stayInEditableContent); }
119     
120     PassRefPtr<Range> toNormalizedRange() const { return m_selection.toNormalizedRange(); }
121
122     void debugRenderer(RenderObject*, bool selected) const;
123     
124     void nodeWillBeRemoved(Node*);
125
126     void setCaretVisible(bool = true);
127     void clearCaretRectIfNeeded();
128     bool recomputeCaretRect(); // returns true if caret rect moved
129     void invalidateCaretRect();
130     void paintCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect);
131
132     // Used to suspend caret blinking while the mouse is down.
133     void setCaretBlinkingSuspended(bool suspended) { m_isCaretBlinkingSuspended = suspended; }
134     bool isCaretBlinkingSuspended() const { return m_isCaretBlinkingSuspended; }
135
136     // Focus
137     void setFocused(bool);
138     bool isFocused() const { return m_focused; }
139     bool isFocusedAndActive() const;
140     void pageActivationChanged();
141
142     // Painting.
143     void updateAppearance();
144
145     void updateSecureKeyboardEntryIfActive();
146
147 #ifndef NDEBUG
148     void formatForDebugger(char* buffer, unsigned length) const;
149     void showTreeForThis() const;
150 #endif
151
152 private:
153     enum EPositionType { START, END, BASE, EXTENT };
154
155     TextDirection directionOfEnclosingBlock();
156
157     VisiblePosition positionForPlatform(bool isGetStart) const;
158     VisiblePosition startForPlatform() const;
159     VisiblePosition endForPlatform() const;
160
161     bool modify(EAlteration, EDirection, TextGranularity, bool userTriggered, Settings*);
162
163     VisiblePosition modifyExtendingRight(TextGranularity);
164     VisiblePosition modifyExtendingForward(TextGranularity);
165     VisiblePosition modifyMovingRight(TextGranularity);
166     VisiblePosition modifyMovingForward(TextGranularity);
167     VisiblePosition modifyExtendingLeft(TextGranularity);
168     VisiblePosition modifyExtendingBackward(TextGranularity);
169     VisiblePosition modifyMovingLeft(TextGranularity);
170     VisiblePosition modifyMovingBackward(TextGranularity);
171
172     void updateCaretRect();
173     IntRect caretRepaintRect() const;
174     bool shouldRepaintCaret(const RenderView* view) const;
175
176     int xPosForVerticalArrowNavigation(EPositionType);
177     
178     void notifyAccessibilityForSelectionChange();
179
180     void focusedOrActiveStateChanged();
181     bool caretRendersInsideNode(Node*) const;
182     
183     IntRect absoluteBoundsForLocalRect(const IntRect&) const;
184
185     void caretBlinkTimerFired(Timer<SelectionController>*);
186
187     void setUseSecureKeyboardEntry(bool);
188
189     Frame* m_frame;
190
191     int m_xPosForVerticalArrowNavigation;
192
193     VisibleSelection m_selection;
194     TextGranularity m_granularity;
195
196     Timer<SelectionController> m_caretBlinkTimer;
197
198     IntRect m_caretRect; // caret rect in coords local to the renderer responsible for painting the caret
199     IntRect m_absCaretBounds; // absolute bounding rect for the caret
200     IntRect m_absoluteCaretRepaintBounds;
201     
202     bool m_caretRectNeedsUpdate; // true if m_caretRect and m_absCaretBounds need to be calculated
203     bool m_absCaretBoundsDirty;
204     bool m_isDirectional;
205     bool m_isDragCaretController;
206     bool m_isCaretBlinkingSuspended;
207     bool m_focused;
208     bool m_caretVisible;
209     bool m_caretPaint;
210 };
211
212 #if !(PLATFORM(MAC) || PLATFORM(GTK))
213 inline void SelectionController::notifyAccessibilityForSelectionChange()
214 {
215 }
216 #endif
217
218 } // namespace WebCore
219
220 #ifndef NDEBUG
221 // Outside the WebCore namespace for ease of invocation from gdb.
222 void showTree(const WebCore::SelectionController&);
223 void showTree(const WebCore::SelectionController*);
224 #endif
225
226 #endif // SelectionController_h
227