• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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