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