• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 VisiblePosition;
41 
42 class SelectionController : public Noncopyable {
43 public:
44     enum EAlteration { MOVE, EXTEND };
45     enum EDirection { FORWARD, BACKWARD, RIGHT, LEFT };
46 
47     SelectionController(Frame* = 0, bool isDragCaretController = false);
48 
rootEditableElement()49     Element* rootEditableElement() const { return m_selection.rootEditableElement(); }
isContentEditable()50     bool isContentEditable() const { return m_selection.isContentEditable(); }
isContentRichlyEditable()51     bool isContentRichlyEditable() const { return m_selection.isContentRichlyEditable(); }
shadowTreeRootNode()52     Node* shadowTreeRootNode() const { return m_selection.shadowTreeRootNode(); }
53 
54     void moveTo(const Range*, EAffinity, bool userTriggered = false);
55     void moveTo(const VisiblePosition&, bool userTriggered = false);
56     void moveTo(const VisiblePosition&, const VisiblePosition&, bool userTriggered = false);
57     void moveTo(const Position&, EAffinity, bool userTriggered = false);
58     void moveTo(const Position&, const Position&, EAffinity, bool userTriggered = false);
59 
selection()60     const VisibleSelection& selection() const { return m_selection; }
61     void setSelection(const VisibleSelection&, bool closeTyping = true, bool clearTypingStyle = true, bool userTriggered = false);
62     bool setSelectedRange(Range*, EAffinity, bool closeTyping);
63     void selectAll();
64     void clear();
65 
66     // Call this after doing user-triggered selections to make it easy to delete the frame you entirely selected.
67     void selectFrameElementInParentIfFullySelected();
68 
69     bool contains(const IntPoint&);
70 
selectionType()71     VisibleSelection::SelectionType selectionType() const { return m_selection.selectionType(); }
72 
affinity()73     EAffinity affinity() const { return m_selection.affinity(); }
74 
75     bool modify(EAlteration, EDirection, TextGranularity, bool userTriggered = false);
76     bool modify(EAlteration, int verticalDistance, bool userTriggered = false);
77     bool expandUsingGranularity(TextGranularity);
78 
79     void setBase(const VisiblePosition&, bool userTriggered = false);
80     void setBase(const Position&, EAffinity, bool userTriggered = false);
81     void setExtent(const VisiblePosition&, bool userTriggered = false);
82     void setExtent(const Position&, EAffinity, bool userTriggered = false);
83 
base()84     Position base() const { return m_selection.base(); }
extent()85     Position extent() const { return m_selection.extent(); }
start()86     Position start() const { return m_selection.start(); }
end()87     Position end() const { return m_selection.end(); }
88 
89     // Return the renderer that is responsible for painting the caret (in the selection start node)
90     RenderObject* caretRenderer() const;
91 
92     // Caret rect local to the caret's renderer
93     IntRect localCaretRect() const;
94     // Bounds of (possibly transformed) caret in absolute coords
95     IntRect absoluteCaretBounds();
96     void setNeedsLayout(bool flag = true);
97 
setLastChangeWasHorizontalExtension(bool b)98     void setLastChangeWasHorizontalExtension(bool b) { m_lastChangeWasHorizontalExtension = b; }
99     void willBeModified(EAlteration, EDirection);
100 
isNone()101     bool isNone() const { return m_selection.isNone(); }
isCaret()102     bool isCaret() const { return m_selection.isCaret(); }
isRange()103     bool isRange() const { return m_selection.isRange(); }
isCaretOrRange()104     bool isCaretOrRange() const { return m_selection.isCaretOrRange(); }
105     bool isInPasswordField() const;
106     bool isAll(StayInEditableContent stayInEditableContent = MustStayInEditableContent) const { return m_selection.isAll(stayInEditableContent); }
107 
toNormalizedRange()108     PassRefPtr<Range> toNormalizedRange() const { return m_selection.toNormalizedRange(); }
109 
110     void debugRenderer(RenderObject*, bool selected) const;
111 
112     void nodeWillBeRemoved(Node*);
113 
114     void setCaretVisible(bool = true);
115     void clearCaretRectIfNeeded();
116     bool recomputeCaretRect(); // returns true if caret rect moved
117     void invalidateCaretRect();
118     void paintCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect);
119 
120     // Used to suspend caret blinking while the mouse is down.
setCaretBlinkingSuspended(bool suspended)121     void setCaretBlinkingSuspended(bool suspended) { m_isCaretBlinkingSuspended = suspended; }
isCaretBlinkingSuspended()122     bool isCaretBlinkingSuspended() const { return m_isCaretBlinkingSuspended; }
123 
124     // Focus
125     void setFocused(bool);
isFocused()126     bool isFocused() const { return m_focused; }
127     bool isFocusedAndActive() const;
128     void pageActivationChanged();
129 
130     // Painting.
131     void updateAppearance();
132 
133 #ifndef NDEBUG
134     void formatForDebugger(char* buffer, unsigned length) const;
135     void showTreeForThis() const;
136 #endif
137 
138 private:
139     enum EPositionType { START, END, BASE, EXTENT };
140 
141     TextDirection directionOfEnclosingBlock();
142 
143     VisiblePosition modifyExtendingRight(TextGranularity);
144     VisiblePosition modifyExtendingForward(TextGranularity);
145     VisiblePosition modifyMovingRight(TextGranularity);
146     VisiblePosition modifyMovingForward(TextGranularity);
147     VisiblePosition modifyExtendingLeft(TextGranularity);
148     VisiblePosition modifyExtendingBackward(TextGranularity);
149     VisiblePosition modifyMovingLeft(TextGranularity);
150     VisiblePosition modifyMovingBackward(TextGranularity);
151 
152     void layout();
153     IntRect caretRepaintRect() const;
154 
155     int xPosForVerticalArrowNavigation(EPositionType);
156 
157     void notifyAccessibilityForSelectionChange();
158 
159     void focusedOrActiveStateChanged();
160     bool caretRendersInsideNode(Node*) const;
161 
162     IntRect absoluteBoundsForLocalRect(const IntRect&) const;
163 
164     void caretBlinkTimerFired(Timer<SelectionController>*);
165 
166     Frame* m_frame;
167 
168     int m_xPosForVerticalArrowNavigation;
169 
170     VisibleSelection m_selection;
171 
172     Timer<SelectionController> m_caretBlinkTimer;
173 
174     IntRect m_caretRect; // caret rect in coords local to the renderer responsible for painting the caret
175     IntRect m_absCaretBounds; // absolute bounding rect for the caret
176     IntRect m_absoluteCaretRepaintBounds;
177 
178     bool m_needsLayout; // true if m_caretRect and m_absCaretBounds need to be calculated
179     bool m_absCaretBoundsDirty;
180     bool m_lastChangeWasHorizontalExtension;
181     bool m_isDragCaretController;
182     bool m_isCaretBlinkingSuspended;
183     bool m_focused;
184     bool m_caretVisible;
185     bool m_caretPaint;
186 };
187 
188 #if !(PLATFORM(MAC) || PLATFORM(GTK))
notifyAccessibilityForSelectionChange()189 inline void SelectionController::notifyAccessibilityForSelectionChange()
190 {
191 }
192 #endif
193 
194 } // namespace WebCore
195 
196 #ifndef NDEBUG
197 // Outside the WebCore namespace for ease of invocation from gdb.
198 void showTree(const WebCore::SelectionController&);
199 void showTree(const WebCore::SelectionController*);
200 #endif
201 
202 #endif // SelectionController_h
203 
204