1 /* 2 * Copyright 2007, The Android Open Source Project 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 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * 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 THE COPYRIGHT HOLDERS ``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 THE COPYRIGHT OWNER 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 CachedNode_h 27 #define CachedNode_h 28 29 #include "CachedDebug.h" 30 #include "CachedNodeType.h" 31 #include "IntRect.h" 32 #include "PlatformString.h" 33 34 #include <wtf/Vector.h> 35 #include <wtf/text/AtomicString.h> 36 37 class SkPicture; 38 39 namespace WebCore { 40 class Node; 41 } 42 43 namespace android { 44 45 class CachedFrame; 46 class CachedRoot; 47 48 class CachedNode { 49 public: 50 // Nodes are rejected because either they are spacially not the best (first set) 51 // or because they have the wrong DOM attribute (in focus, a focused child, etc) 52 // findClosest() gives only spacially rejected nodes a second chance 53 enum Condition { // if bigger than 32, increase bitfield size below 54 // rejections that get a second chance 55 NOT_REJECTED = 0, 56 SECOND_CHANCE_START = NOT_REJECTED, // must be first in list 57 BUTTED_UP, 58 CENTER_FURTHER, 59 CLOSER, 60 CLOSER_IN_CURSOR, 61 CLOSER_OVERLAP, 62 CLOSER_TOP, 63 NAVABLE, 64 FURTHER, 65 IN_UMBRA, 66 IN_WORKING, 67 LEFTMOST, 68 NOT_ENCLOSING_CURSOR, 69 OVERLAP_OR_EDGE_FURTHER, 70 PREFERRED, // better overlap measure 71 SECOND_CHANCE_END = PREFERRED, // must be last in list 72 // rejections that don't get a second chance 73 ANCHOR_IN_ANCHOR, 74 BEST_DIRECTION, // can be reached by another direction 75 CHILD, 76 DISABLED, 77 HIGHER_TAB_INDEX, 78 IN_CURSOR, 79 IN_CURSOR_CHILDREN, 80 NOT_CURSOR_NODE, 81 OUTSIDE_OF_BEST, // containership 82 OUTSIDE_OF_ORIGINAL, // containership 83 UNDER_LAYER, 84 CONDITION_SIZE // FIXME: test that CONDITION_SIZE fits in mCondition 85 }; 86 CachedNode() { 87 // The node is initiaized to 0 in its array, so nothing to do in the 88 // constructor 89 } 90 91 WebCore::IntRect bounds(const CachedFrame* ) const; 92 int childFrameIndex() const { return isFrame() ? mDataIndex : -1; } 93 void clearCondition() const { mCondition = NOT_REJECTED; } 94 void clearCursor(CachedFrame* ); 95 static bool Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, 96 WTF::Vector<WebCore::IntRect>* rings); 97 bool clip(const WebCore::IntRect& ); 98 bool clippedOut() { return mClippedOut; } 99 int colorIndex() const { return mColorIndex; } 100 WebCore::IntRect cursorRingBounds(const CachedFrame* ) const; 101 void cursorRings(const CachedFrame* , WTF::Vector<WebCore::IntRect>* ) const; 102 bool disabled() const { return mDisabled; } 103 const CachedNode* document() const { return &this[-mIndex]; } 104 void fixUpCursorRects(const CachedFrame* frame); 105 const WTF::String& getExport() const { return mExport; } 106 bool hasCursorRing() const { return mHasCursorRing; } 107 bool hasMouseOver() const { return mHasMouseOver; } 108 void hideCursor(CachedFrame* ); 109 WebCore::IntRect hitBounds(const CachedFrame* ) const; 110 int index() const { return mIndex; } 111 void init(WebCore::Node* node); 112 bool isAnchor() const { return mType == ANCHOR_CACHEDNODETYPE; } 113 bool isContentEditable() const { return mType == CONTENT_EDITABLE_CACHEDNODETYPE; } 114 bool isCursor() const { return mIsCursor; } 115 bool isArea() const { return mType == AREA_CACHEDNODETYPE; } 116 bool isFocus() const { return mIsFocus; } 117 bool isFrame() const { return mType == FRAME_CACHEDNODETYPE; } 118 bool isHidden() const { return mIsHidden; } 119 bool isInLayer() const { return mIsInLayer; } 120 bool isNavable(const CachedFrame* frame, const WebCore::IntRect& clip) const { 121 return clip.intersects(bounds(frame)); 122 } 123 bool isPlugin() const { return mType == PLUGIN_CACHEDNODETYPE; } 124 bool isSelect() const { return mType == SELECT_CACHEDNODETYPE; } 125 bool isSyntheticLink() const { 126 return mType >= ADDRESS_CACHEDNODETYPE && mType <= PHONE_CACHEDNODETYPE; 127 } 128 bool isTextField(const CachedFrame*) const; 129 bool isTextInput() const { return mType == TEXT_INPUT_CACHEDNODETYPE; } 130 bool isTransparent() const { return mIsTransparent; } 131 bool isUnclipped() const { return mIsUnclipped; } 132 // localXXX functions are used only for drawing cursor rings 133 WebCore::IntRect localBounds(const CachedFrame* ) const; 134 void localCursorRings(const CachedFrame* , 135 WTF::Vector<WebCore::IntRect>* ) const; 136 WebCore::IntRect localHitBounds(const CachedFrame* ) const; 137 WebCore::IntRect localRing(const CachedFrame* , size_t part) const; 138 void move(int x, int y); 139 int navableRects() const { return mCursorRing.size(); } 140 void* nodePointer() const { return mNode; } 141 bool noSecondChance() const { return mCondition > SECOND_CHANCE_END; } 142 const WebCore::IntRect& originalAbsoluteBounds() const { 143 return mOriginalAbsoluteBounds; } 144 const CachedNode* parent() const { return document() + mParentIndex; } 145 void* parentGroup() const { return mParentGroup; } 146 int parentIndex() const { return mParentIndex; } 147 bool partRectsContains(const CachedNode* other) const; 148 const WebCore::IntRect& rawBounds() const { return mBounds; } 149 void reset(); 150 WebCore::IntRect ring(const CachedFrame* , size_t part) const; 151 const WTF::Vector<WebCore::IntRect>& rings() const { return mCursorRing; } 152 void setBounds(const WebCore::IntRect& bounds) { mBounds = bounds; } 153 void setClippedOut(bool clipped) { mClippedOut = clipped; } 154 void setColorIndex(int index) { mColorIndex = index; } 155 void setCondition(Condition condition) const { mCondition = condition; } 156 void setDataIndex(int index) { mDataIndex = index; } 157 void setDisabled(bool disabled) { mDisabled = disabled; } 158 void setExport(const WTF::String& exported) { mExport = exported; } 159 void setHasCursorRing(bool hasRing) { mHasCursorRing = hasRing; } 160 void setHasMouseOver(bool hasMouseOver) { mHasMouseOver = hasMouseOver; } 161 void setHitBounds(const WebCore::IntRect& bounds) { mHitBounds = bounds; } 162 void setOriginalAbsoluteBounds(const WebCore::IntRect& bounds) { 163 mOriginalAbsoluteBounds = bounds; } 164 void setIndex(int index) { mIndex = index; } 165 void setIsCursor(bool isCursor) { mIsCursor = isCursor; } 166 void setIsFocus(bool isFocus) { mIsFocus = isFocus; } 167 void setIsInLayer(bool isInLayer) { mIsInLayer = isInLayer; } 168 void setIsParentAnchor(bool isAnchor) { mIsParentAnchor = isAnchor; } 169 void setIsTransparent(bool isTransparent) { mIsTransparent = isTransparent; } 170 void setIsUnclipped(bool unclipped) { mIsUnclipped = unclipped; } 171 void setLast() { mLast = true; } 172 void setParentGroup(void* group) { mParentGroup = group; } 173 void setParentIndex(int parent) { mParentIndex = parent; } 174 void setSingleImage(bool single) { mSingleImage = single; } 175 void setTabIndex(int index) { mTabIndex = index; } 176 void setType(CachedNodeType type) { mType = type; } 177 void show() { mIsHidden = false; } 178 bool singleImage() const { return mSingleImage; } 179 int tabIndex() const { return mTabIndex; } 180 int textInputIndex() const { return isTextInput() ? mDataIndex : -1; } 181 const CachedNode* traverseNextNode() const { return mLast ? NULL : &this[1]; } 182 bool useBounds() const { return mUseBounds; } 183 bool useHitBounds() const { return mUseHitBounds; } 184 bool wantsKeyEvents() const { return isTextInput() || isPlugin() 185 || isContentEditable() || isFrame(); } 186 private: 187 friend class CacheBuilder; 188 WTF::String mExport; 189 WebCore::IntRect mBounds; 190 WebCore::IntRect mHitBounds; 191 WebCore::IntRect mOriginalAbsoluteBounds; 192 WTF::Vector<WebCore::IntRect> mCursorRing; 193 void* mNode; // WebCore::Node*, only used to match pointers 194 void* mParentGroup; // WebCore::Node*, only used to match pointers 195 int mDataIndex; // child frame if a frame; input data index; or -1 196 int mIndex; // index of itself, to find first in array (document) 197 int mParentIndex; 198 int mTabIndex; 199 int mColorIndex; // index to ring color and other stylable properties 200 mutable Condition mCondition : 5; // why the node was not chosen on the first pass 201 CachedNodeType mType : 4; 202 bool mClippedOut : 1; 203 bool mDisabled : 1; 204 bool mFixedUpCursorRects : 1; 205 bool mHasCursorRing : 1; 206 bool mHasMouseOver : 1; 207 bool mIsCursor : 1; 208 bool mIsFocus : 1; 209 bool mIsHidden : 1; 210 bool mIsInLayer : 1; 211 bool mIsParentAnchor : 1; 212 bool mIsTransparent : 1; 213 bool mIsUnclipped : 1; 214 bool mLast : 1; // true if this is the last node in a group 215 bool mSingleImage : 1; 216 bool mUseBounds : 1; 217 bool mUseHitBounds : 1; 218 #ifdef BROWSER_DEBUG 219 public: 220 WebCore::Node* webCoreNode() const { return (WebCore::Node*) mNode; } 221 bool mDisplayMeasure; 222 mutable bool mInCompare; 223 int mSideDistance; 224 int mSecondSide; 225 #endif 226 #if DEBUG_NAV_UI || DUMP_NAV_CACHE 227 public: 228 class Debug { 229 public: 230 CachedNode* base() const; 231 const char* condition(Condition t) const; 232 void print() const; 233 const char* type(CachedNodeType t) const; 234 #if DUMP_NAV_CACHE 235 int mNodeIndex; 236 int mParentGroupIndex; 237 #endif 238 } mDebug; 239 friend class CachedNode::Debug; 240 #endif 241 }; 242 243 } 244 245 #endif 246