2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef SelectionController_h
27 #define SelectionController_h
29 #include "EditingStyle.h"
32 #include "ScrollBehavior.h"
34 #include "VisibleSelection.h"
35 #include <wtf/Noncopyable.h>
40 class CSSMutableStyleDeclaration;
41 class GraphicsContext;
42 class HTMLFormElement;
46 class VisiblePosition;
48 enum DirectionalityPolicy { MakeNonDirectionalSelection, MakeDirectionalSelection };
50 class SelectionController : public Noncopyable {
52 enum EAlteration { AlterationMove, AlterationExtend };
53 enum EDirection { DirectionForward, DirectionBackward, DirectionRight, DirectionLeft };
54 enum CursorAlignOnScroll { AlignCursorOnScrollIfNeeded,
55 AlignCursorOnScrollAlways };
57 SelectionController(Frame* = 0, bool isDragCaretController = false);
59 Element* rootEditableElement() const { return m_selection.rootEditableElement(); }
60 bool isContentEditable() const { return m_selection.isContentEditable(); }
61 bool isContentRichlyEditable() const { return m_selection.isContentRichlyEditable(); }
62 Node* shadowTreeRootNode() const { return m_selection.shadowTreeRootNode(); }
64 void moveTo(const Range*, EAffinity, bool userTriggered = false);
65 void moveTo(const VisiblePosition&, bool userTriggered = false, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded);
66 void moveTo(const VisiblePosition&, const VisiblePosition&, bool userTriggered = false);
67 void moveTo(const Position&, EAffinity, bool userTriggered = false);
68 void moveTo(const Position&, const Position&, EAffinity, bool userTriggered = false);
70 const VisibleSelection& selection() const { return m_selection; }
71 void setSelection(const VisibleSelection&, bool closeTyping = true, bool clearTypingStyle = true, bool userTriggered = false, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded, TextGranularity = CharacterGranularity, DirectionalityPolicy = MakeDirectionalSelection);
72 void setSelection(const VisibleSelection& selection, TextGranularity granularity, DirectionalityPolicy directionality = MakeDirectionalSelection) { setSelection(selection, true, true, false, AlignCursorOnScrollIfNeeded, granularity, directionality); }
73 bool setSelectedRange(Range*, EAffinity, bool closeTyping);
77 // Call this after doing user-triggered selections to make it easy to delete the frame you entirely selected.
78 void selectFrameElementInParentIfFullySelected();
80 bool contains(const IntPoint&);
82 VisibleSelection::SelectionType selectionType() const { return m_selection.selectionType(); }
84 EAffinity affinity() const { return m_selection.affinity(); }
86 bool modify(EAlteration, EDirection, TextGranularity, bool userTriggered = false);
87 bool modify(EAlteration, int verticalDistance, bool userTriggered = false, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded);
88 TextGranularity granularity() const { return m_granularity; }
90 void setStart(const VisiblePosition &, bool userTriggered = false);
91 void setEnd(const VisiblePosition &, bool userTriggered = false);
93 void setBase(const VisiblePosition&, bool userTriggered = false);
94 void setBase(const Position&, EAffinity, bool userTriggered = false);
95 void setExtent(const VisiblePosition&, bool userTriggered = false);
96 void setExtent(const Position&, EAffinity, bool userTriggered = false);
98 Position base() const { return m_selection.base(); }
99 Position extent() const { return m_selection.extent(); }
100 Position start() const { return m_selection.start(); }
101 Position end() const { return m_selection.end(); }
103 // Return the renderer that is responsible for painting the caret (in the selection start node)
104 RenderObject* caretRenderer() const;
106 // Caret rect local to the caret's renderer
107 IntRect localCaretRect();
108 IntRect localCaretRectForPainting() const { return m_caretRect; }
110 // Bounds of (possibly transformed) caret in absolute coords
111 IntRect absoluteCaretBounds();
112 void setCaretRectNeedsUpdate(bool flag = true);
114 void setIsDirectional(bool);
115 void willBeModified(EAlteration, EDirection);
117 bool isNone() const { return m_selection.isNone(); }
118 bool isCaret() const { return m_selection.isCaret(); }
119 bool isRange() const { return m_selection.isRange(); }
120 bool isCaretOrRange() const { return m_selection.isCaretOrRange(); }
121 bool isInPasswordField() const;
122 bool isAll(StayInEditableContent stayInEditableContent = MustStayInEditableContent) const { return m_selection.isAll(stayInEditableContent); }
124 PassRefPtr<Range> toNormalizedRange() const { return m_selection.toNormalizedRange(); }
126 void debugRenderer(RenderObject*, bool selected) const;
128 void nodeWillBeRemoved(Node*);
130 void setCaretVisible(bool = true);
131 void clearCaretRectIfNeeded();
132 bool recomputeCaretRect(); // returns true if caret rect moved
133 void invalidateCaretRect();
134 void paintCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect);
136 // Used to suspend caret blinking while the mouse is down.
137 void setCaretBlinkingSuspended(bool suspended) { m_isCaretBlinkingSuspended = suspended; }
138 bool isCaretBlinkingSuspended() const { return m_isCaretBlinkingSuspended; }
141 void setFocused(bool);
142 bool isFocused() const { return m_focused; }
143 bool isFocusedAndActive() const;
144 void pageActivationChanged();
147 void updateAppearance();
149 void updateSecureKeyboardEntryIfActive();
152 void formatForDebugger(char* buffer, unsigned length) const;
153 void showTreeForThis() const;
156 bool shouldChangeSelection(const VisibleSelection&) const;
157 bool shouldDeleteSelection(const VisibleSelection&) const;
158 void setFocusedNodeIfNeeded();
159 void notifyRendererOfSelectionChange(bool userTriggered);
161 void paintDragCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const;
163 EditingStyle* typingStyle() const;
164 PassRefPtr<CSSMutableStyleDeclaration> copyTypingStyle() const;
165 void setTypingStyle(PassRefPtr<EditingStyle>);
166 void clearTypingStyle();
168 FloatRect bounds(bool clipToVisibleContent = true) const;
170 void getClippedVisibleTextRectangles(Vector<FloatRect>&) const;
172 HTMLFormElement* currentForm() const;
174 void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, bool revealExtent = false);
175 void setSelectionFromNone();
178 enum EPositionType { START, END, BASE, EXTENT };
180 TextDirection directionOfEnclosingBlock();
182 VisiblePosition positionForPlatform(bool isGetStart) const;
183 VisiblePosition startForPlatform() const;
184 VisiblePosition endForPlatform() const;
186 VisiblePosition modifyExtendingRight(TextGranularity);
187 VisiblePosition modifyExtendingForward(TextGranularity);
188 VisiblePosition modifyMovingRight(TextGranularity);
189 VisiblePosition modifyMovingForward(TextGranularity);
190 VisiblePosition modifyExtendingLeft(TextGranularity);
191 VisiblePosition modifyExtendingBackward(TextGranularity);
192 VisiblePosition modifyMovingLeft(TextGranularity);
193 VisiblePosition modifyMovingBackward(TextGranularity);
195 void updateCaretRect();
196 IntRect caretRepaintRect() const;
197 bool shouldRepaintCaret(const RenderView* view) const;
199 int xPosForVerticalArrowNavigation(EPositionType);
201 void notifyAccessibilityForSelectionChange();
203 void focusedOrActiveStateChanged();
204 bool caretRendersInsideNode(Node*) const;
206 IntRect absoluteBoundsForLocalRect(const IntRect&) const;
208 void caretBlinkTimerFired(Timer<SelectionController>*);
210 void setUseSecureKeyboardEntry(bool);
214 int m_xPosForVerticalArrowNavigation;
216 VisibleSelection m_selection;
217 TextGranularity m_granularity;
219 RefPtr<EditingStyle> m_typingStyle;
221 Timer<SelectionController> m_caretBlinkTimer;
223 IntRect m_caretRect; // caret rect in coords local to the renderer responsible for painting the caret
224 IntRect m_absCaretBounds; // absolute bounding rect for the caret
225 IntRect m_absoluteCaretRepaintBounds;
227 bool m_caretRectNeedsUpdate; // true if m_caretRect and m_absCaretBounds need to be calculated
228 bool m_absCaretBoundsDirty;
229 bool m_isDirectional;
230 bool m_isDragCaretController;
231 bool m_isCaretBlinkingSuspended;
237 inline EditingStyle* SelectionController::typingStyle() const
239 return m_typingStyle.get();
242 inline PassRefPtr<CSSMutableStyleDeclaration> SelectionController::copyTypingStyle() const
244 if (!m_typingStyle || !m_typingStyle->style())
246 return m_typingStyle->style()->copy();
249 inline void SelectionController::clearTypingStyle()
251 m_typingStyle.clear();
254 inline void SelectionController::setTypingStyle(PassRefPtr<EditingStyle> style)
256 m_typingStyle = style;
259 #if !(PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(CHROMIUM))
260 inline void SelectionController::notifyAccessibilityForSelectionChange()
265 } // namespace WebCore
268 // Outside the WebCore namespace for ease of invocation from gdb.
269 void showTree(const WebCore::SelectionController&);
270 void showTree(const WebCore::SelectionController*);
273 #endif // SelectionController_h