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