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 "Range.h" 31 #include "VisibleSelection.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 : public 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 VisibleSelection& selection() const { return m_sel; } 60 void setSelection(const VisibleSelection&, 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 selectionType()70 VisibleSelection::SelectionType selectionType() const { return m_sel.selectionType(); } 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 bool isAll(StayInEditableContent stayInEditableContent = MustStayInEditableContent) const { return m_sel.isAll(stayInEditableContent); } 106 toNormalizedRange()107 PassRefPtr<Range> toNormalizedRange() const { return m_sel.toNormalizedRange(); } 108 109 void debugRenderer(RenderObject*, bool selected) const; 110 111 void nodeWillBeRemoved(Node*); 112 113 bool recomputeCaretRect(); // returns true if caret rect moved 114 void invalidateCaretRect(); 115 void paintCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect); 116 117 // Used to suspend caret blinking while the mouse is down. setCaretBlinkingSuspended(bool suspended)118 void setCaretBlinkingSuspended(bool suspended) { m_isCaretBlinkingSuspended = suspended; } isCaretBlinkingSuspended()119 bool isCaretBlinkingSuspended() const { return m_isCaretBlinkingSuspended; } 120 121 // Focus 122 void setFocused(bool); isFocused()123 bool isFocused() const { return m_focused; } 124 bool isFocusedAndActive() const; 125 void pageActivationChanged(); 126 127 #ifndef NDEBUG 128 void formatForDebugger(char* buffer, unsigned length) const; 129 void showTreeForThis() const; 130 #endif 131 132 private: 133 enum EPositionType { START, END, BASE, EXTENT }; 134 135 TextDirection directionOfEnclosingBlock(); 136 137 VisiblePosition modifyExtendingRight(TextGranularity); 138 VisiblePosition modifyExtendingForward(TextGranularity); 139 VisiblePosition modifyMovingRight(TextGranularity); 140 VisiblePosition modifyMovingForward(TextGranularity); 141 VisiblePosition modifyExtendingLeft(TextGranularity); 142 VisiblePosition modifyExtendingBackward(TextGranularity); 143 VisiblePosition modifyMovingLeft(TextGranularity); 144 VisiblePosition modifyMovingBackward(TextGranularity); 145 146 void layout(); 147 IntRect caretRepaintRect() const; 148 149 int xPosForVerticalArrowNavigation(EPositionType); 150 151 #if PLATFORM(MAC) || PLATFORM(GTK) 152 void notifyAccessibilityForSelectionChange(); 153 #else notifyAccessibilityForSelectionChange()154 void notifyAccessibilityForSelectionChange() {}; 155 #endif 156 157 void focusedOrActiveStateChanged(); 158 bool caretRendersInsideNode(Node*) const; 159 160 IntRect absoluteBoundsForLocalRect(const IntRect&) const; 161 162 Frame* m_frame; 163 int m_xPosForVerticalArrowNavigation; 164 165 VisibleSelection m_sel; 166 167 IntRect m_caretRect; // caret rect in coords local to the renderer responsible for painting the caret 168 IntRect m_absCaretBounds; // absolute bounding rect for the caret 169 IntRect m_absoluteCaretRepaintBounds; 170 171 bool m_needsLayout : 1; // true if the caret and expectedVisible rectangles need to be calculated 172 bool m_absCaretBoundsDirty: 1; 173 bool m_lastChangeWasHorizontalExtension : 1; 174 bool m_isDragCaretController : 1; 175 bool m_isCaretBlinkingSuspended : 1; 176 bool m_focused : 1; 177 178 }; 179 180 inline bool operator==(const SelectionController& a, const SelectionController& b) 181 { 182 return a.start() == b.start() && a.end() == b.end() && a.affinity() == b.affinity(); 183 } 184 185 inline bool operator!=(const SelectionController& a, const SelectionController& b) 186 { 187 return !(a == b); 188 } 189 190 } // namespace WebCore 191 192 #ifndef NDEBUG 193 // Outside the WebCore namespace for ease of invocation from gdb. 194 void showTree(const WebCore::SelectionController&); 195 void showTree(const WebCore::SelectionController*); 196 #endif 197 198 #endif // SelectionController_h 199 200