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