tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebCore / editing / FrameSelection.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 FrameSelection_h
27 #define FrameSelection_h
28
29 #include "EditingStyle.h"
30 #include "IntRect.h"
31 #include "LayoutTypes.h"
32 #include "Range.h"
33 #include "ScrollBehavior.h"
34 #include "Timer.h"
35 #include "VisibleSelection.h"
36 #include <wtf/Noncopyable.h>
37
38 namespace WebCore {
39
40 class CharacterData;
41 class CSSMutableStyleDeclaration;
42 class Frame;
43 class GraphicsContext;
44 class HTMLFormElement;
45 class RenderObject;
46 class RenderView;
47 class Settings;
48 class VisiblePosition;
49
50 enum EUserTriggered { NotUserTriggered = 0, UserTriggered = 1 };
51
52 class CaretBase {
53     WTF_MAKE_NONCOPYABLE(CaretBase);
54     WTF_MAKE_FAST_ALLOCATED;
55 protected:
56     enum CaretVisibility { Visible, Hidden };
57     explicit CaretBase(CaretVisibility = Hidden);
58
59     void invalidateCaretRect(Node*, bool caretRectChanged = false);
60     void clearCaretRect();
61     bool updateCaretRect(Document*, const VisiblePosition& caretPosition);
62     LayoutRect absoluteBoundsForLocalRect(Node*, const LayoutRect&) const;
63     LayoutRect caretRepaintRect(Node*) const;
64     bool shouldRepaintCaret(const RenderView*, bool isContentEditable) const;
65     void paintCaret(Node*, GraphicsContext*, const LayoutPoint&, const LayoutRect& clipRect) const;
66     RenderObject* caretRenderer(Node*) const;
67
68     const LayoutRect& localCaretRectWithoutUpdate() const { return m_caretLocalRect; }
69
70     bool shouldUpdateCaretRect() const { return m_caretRectNeedsUpdate; }
71     void setCaretRectNeedsUpdate() { m_caretRectNeedsUpdate = true; }
72
73     void setCaretVisibility(CaretVisibility visibility) { m_caretVisibility = visibility; }
74     bool caretIsVisible() const { return m_caretVisibility == Visible; }
75     CaretVisibility caretVisibility() const { return m_caretVisibility; }
76
77 private:
78     LayoutRect m_caretLocalRect; // caret rect in coords local to the renderer responsible for painting the caret
79     bool m_caretRectNeedsUpdate; // true if m_caretRect (and m_absCaretBounds in FrameSelection) need to be calculated
80     CaretVisibility m_caretVisibility;
81 };
82
83 class DragCaretController : private CaretBase {
84     WTF_MAKE_NONCOPYABLE(DragCaretController);
85     WTF_MAKE_FAST_ALLOCATED;
86 public:
87     DragCaretController();
88
89     RenderObject* caretRenderer() const;
90     void paintDragCaret(Frame*, GraphicsContext*, const LayoutPoint&, const LayoutRect& clipRect) const;
91
92     bool isContentEditable() const { return m_position.rootEditableElement(); }
93     bool isContentRichlyEditable() const;
94
95     bool hasCaret() const { return m_position.isNotNull(); }
96     const VisiblePosition& caretPosition() { return m_position; }
97     void setCaretPosition(const VisiblePosition&);
98     void clear() { setCaretPosition(VisiblePosition()); }
99
100     void nodeWillBeRemoved(Node*);
101
102 private:
103     VisiblePosition m_position;
104 };
105
106 class FrameSelection : private CaretBase {
107     WTF_MAKE_NONCOPYABLE(FrameSelection);
108     WTF_MAKE_FAST_ALLOCATED;
109 public:
110     enum EAlteration { AlterationMove, AlterationExtend };
111     enum CursorAlignOnScroll { AlignCursorOnScrollIfNeeded,
112                                AlignCursorOnScrollAlways };
113     enum SetSelectionOption {
114         // 1 << 0 is reserved for EUserTriggered
115         CloseTyping = 1 << 1,
116         ClearTypingStyle = 1 << 2,
117         SpellCorrectionTriggered = 1 << 3,
118         DoNotSetFocus = 1 << 4,
119     };
120     typedef unsigned SetSelectionOptions; // Union of values in SetSelectionOption and EUserTriggered
121     static inline EUserTriggered selectionOptionsToUserTriggered(SetSelectionOptions options)
122     {
123         return static_cast<EUserTriggered>(options & UserTriggered);
124     }
125
126     FrameSelection(Frame* = 0);
127
128     Element* rootEditableElement() const { return m_selection.rootEditableElement(); }
129     Element* rootEditableElementOrDocumentElement() const;
130     bool isContentEditable() const { return m_selection.isContentEditable(); }
131     bool isContentRichlyEditable() const { return m_selection.isContentRichlyEditable(); }
132      
133     void moveTo(const Range*, EAffinity, EUserTriggered = NotUserTriggered);
134     void moveTo(const VisiblePosition&, EUserTriggered = NotUserTriggered, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded);
135     void moveTo(const VisiblePosition&, const VisiblePosition&, EUserTriggered = NotUserTriggered);
136     void moveTo(const Position&, EAffinity, EUserTriggered = NotUserTriggered);
137     void moveTo(const Position&, const Position&, EAffinity, EUserTriggered = NotUserTriggered);
138
139     const VisibleSelection& selection() const { return m_selection; }
140     void setSelection(const VisibleSelection&, SetSelectionOptions = CloseTyping | ClearTypingStyle, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded, TextGranularity = CharacterGranularity);
141     void setSelection(const VisibleSelection& selection, TextGranularity granularity) { setSelection(selection, CloseTyping | ClearTypingStyle, AlignCursorOnScrollIfNeeded, granularity); }
142     bool setSelectedRange(Range*, EAffinity, bool closeTyping);
143     void selectAll();
144     void clear();
145     
146     // Call this after doing user-triggered selections to make it easy to delete the frame you entirely selected.
147     void selectFrameElementInParentIfFullySelected();
148
149     bool contains(const LayoutPoint&);
150
151     VisibleSelection::SelectionType selectionType() const { return m_selection.selectionType(); }
152
153     EAffinity affinity() const { return m_selection.affinity(); }
154
155     bool modify(EAlteration, SelectionDirection, TextGranularity, EUserTriggered = NotUserTriggered);
156     enum VerticalDirection { DirectionUp, DirectionDown };
157     bool modify(EAlteration, unsigned verticalDistance, VerticalDirection, EUserTriggered = NotUserTriggered, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded);
158
159     TextGranularity granularity() const { return m_granularity; }
160
161     void setStart(const VisiblePosition &, EUserTriggered = NotUserTriggered);
162     void setEnd(const VisiblePosition &, EUserTriggered = NotUserTriggered);
163     
164     void setBase(const VisiblePosition&, EUserTriggered = NotUserTriggered);
165     void setBase(const Position&, EAffinity, EUserTriggered = NotUserTriggered);
166     void setExtent(const VisiblePosition&, EUserTriggered = NotUserTriggered);
167     void setExtent(const Position&, EAffinity, EUserTriggered = NotUserTriggered);
168
169     Position base() const { return m_selection.base(); }
170     Position extent() const { return m_selection.extent(); }
171     Position start() const { return m_selection.start(); }
172     Position end() const { return m_selection.end(); }
173
174     // Return the renderer that is responsible for painting the caret (in the selection start node)
175     RenderObject* caretRenderer() const;
176
177     // Caret rect local to the caret's renderer
178     LayoutRect localCaretRect();
179
180     // Bounds of (possibly transformed) caret in absolute coords
181     LayoutRect absoluteCaretBounds();
182     void setCaretRectNeedsUpdate() { CaretBase::setCaretRectNeedsUpdate(); }
183
184     void willBeModified(EAlteration, SelectionDirection);
185
186     bool isNone() const { return m_selection.isNone(); }
187     bool isCaret() const { return m_selection.isCaret(); }
188     bool isRange() const { return m_selection.isRange(); }
189     bool isCaretOrRange() const { return m_selection.isCaretOrRange(); }
190     bool isInPasswordField() const;
191     bool isAll(EditingBoundaryCrossingRule rule = CannotCrossEditingBoundary) const { return m_selection.isAll(rule); }
192     
193     PassRefPtr<Range> toNormalizedRange() const { return m_selection.toNormalizedRange(); }
194
195     void debugRenderer(RenderObject*, bool selected) const;
196
197     void nodeWillBeRemoved(Node*);
198     void textWillBeReplaced(CharacterData*, unsigned offset, unsigned oldLength, unsigned newLength);
199
200     void setCaretVisible(bool caretIsVisible) { setCaretVisibility(caretIsVisible ? Visible : Hidden); }
201     void clearCaretRectIfNeeded();
202     bool recomputeCaretRect();
203     void invalidateCaretRect();
204     void paintCaret(GraphicsContext*, const LayoutPoint&, const LayoutRect& clipRect);
205
206     // Used to suspend caret blinking while the mouse is down.
207     void setCaretBlinkingSuspended(bool suspended) { m_isCaretBlinkingSuspended = suspended; }
208     bool isCaretBlinkingSuspended() const { return m_isCaretBlinkingSuspended; }
209
210     // Focus
211     void setFocused(bool);
212     bool isFocused() const { return m_focused; }
213     bool isFocusedAndActive() const;
214     void pageActivationChanged();
215
216     // Painting.
217     void updateAppearance();
218
219     void updateSecureKeyboardEntryIfActive();
220
221 #ifndef NDEBUG
222     void formatForDebugger(char* buffer, unsigned length) const;
223     void showTreeForThis() const;
224 #endif
225
226     bool shouldChangeSelection(const VisibleSelection&) const;
227     bool shouldDeleteSelection(const VisibleSelection&) const;
228     enum EndPointsAdjustmentMode { AdjustEndpointsAtBidiBoundary, DoNotAdjsutEndpoints };
229     void setNonDirectionalSelectionIfNeeded(const VisibleSelection&, TextGranularity, EndPointsAdjustmentMode = DoNotAdjsutEndpoints);
230     void setFocusedNodeIfNeeded();
231     void notifyRendererOfSelectionChange(EUserTriggered);
232
233     void paintDragCaret(GraphicsContext*, const LayoutPoint&, const LayoutRect& clipRect) const;
234
235     EditingStyle* typingStyle() const;
236     PassRefPtr<CSSMutableStyleDeclaration> copyTypingStyle() const;
237     void setTypingStyle(PassRefPtr<EditingStyle>);
238     void clearTypingStyle();
239
240     FloatRect bounds(bool clipToVisibleContent = true) const;
241
242     void getClippedVisibleTextRectangles(Vector<FloatRect>&) const;
243
244     HTMLFormElement* currentForm() const;
245
246     void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, bool revealExtent = false);
247     void setSelectionFromNone();
248
249 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
250     bool canEditableSelectRange() const;
251 #endif
252
253 private:
254     enum EPositionType { START, END, BASE, EXTENT };
255
256     void respondToNodeModification(Node*, bool baseRemoved, bool extentRemoved, bool startRemoved, bool endRemoved);
257     TextDirection directionOfEnclosingBlock();
258     TextDirection directionOfSelection();
259
260     VisiblePosition positionForPlatform(bool isGetStart) const;
261     VisiblePosition startForPlatform() const;
262     VisiblePosition endForPlatform() const;
263
264     VisiblePosition modifyExtendingRight(TextGranularity);
265     VisiblePosition modifyExtendingForward(TextGranularity);
266     VisiblePosition modifyMovingRight(TextGranularity);
267     VisiblePosition modifyMovingForward(TextGranularity);
268     VisiblePosition modifyExtendingLeft(TextGranularity);
269     VisiblePosition modifyExtendingBackward(TextGranularity);
270     VisiblePosition modifyMovingLeft(TextGranularity);
271     VisiblePosition modifyMovingBackward(TextGranularity);
272
273     LayoutUnit lineDirectionPointForBlockDirectionNavigation(EPositionType);
274     
275     void notifyAccessibilityForSelectionChange();
276
277     void focusedOrActiveStateChanged();
278
279     void caretBlinkTimerFired(Timer<FrameSelection>*);
280
281     void setUseSecureKeyboardEntry(bool);
282
283     void setCaretVisibility(CaretVisibility);
284
285     bool dispatchSelectStart();
286   
287     bool visualWordMovementEnabled() const;
288
289     Frame* m_frame;
290
291     LayoutUnit m_xPosForVerticalArrowNavigation;
292
293     VisibleSelection m_selection;
294     VisiblePosition m_originalBase; // Used to store base before the adjustment at bidi boundary
295     TextGranularity m_granularity;
296
297     RefPtr<EditingStyle> m_typingStyle;
298
299     Timer<FrameSelection> m_caretBlinkTimer;
300     LayoutRect m_absCaretBounds; // absolute bounding rect for the caret
301     LayoutRect m_absoluteCaretRepaintBounds;
302     bool m_absCaretBoundsDirty : 1;
303     bool m_caretPaint : 1;
304     bool m_isCaretBlinkingSuspended : 1;
305     bool m_focused : 1;
306 };
307
308 inline EditingStyle* FrameSelection::typingStyle() const
309 {
310     return m_typingStyle.get();
311 }
312
313 inline void FrameSelection::clearTypingStyle()
314 {
315     m_typingStyle.clear();
316 }
317
318 inline void FrameSelection::setTypingStyle(PassRefPtr<EditingStyle> style)
319 {
320     m_typingStyle = style;
321 }
322
323 #if !(PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(CHROMIUM))
324 inline void FrameSelection::notifyAccessibilityForSelectionChange()
325 {
326 }
327 #endif
328
329 } // namespace WebCore
330
331 #ifndef NDEBUG
332 // Outside the WebCore namespace for ease of invocation from gdb.
333 void showTree(const WebCore::FrameSelection&);
334 void showTree(const WebCore::FrameSelection*);
335 #endif
336
337 #endif // FrameSelection_h
338