• 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 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     };
CachedNode()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;
childFrameIndex()92     int childFrameIndex() const { return isFrame() ? mDataIndex : -1; }
clearCondition()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& );
clippedOut()98     bool clippedOut() { return mClippedOut; }
colorIndex()99     int colorIndex() const { return mColorIndex; }
100     WebCore::IntRect cursorRingBounds(const CachedFrame* ) const;
101     void cursorRings(const CachedFrame* , WTF::Vector<WebCore::IntRect>* ) const;
disabled()102     bool disabled() const { return mDisabled; }
document()103     const CachedNode* document() const { return &this[-mIndex]; }
104     void fixUpCursorRects(const CachedFrame* frame);
getExport()105     const WTF::String& getExport() const { return mExport; }
hasCursorRing()106     bool hasCursorRing() const { return mHasCursorRing; }
hasMouseOver()107     bool hasMouseOver() const { return mHasMouseOver; }
108     void hideCursor(CachedFrame* );
109     WebCore::IntRect hitBounds(const CachedFrame* ) const;
index()110     int index() const { return mIndex; }
111     void init(WebCore::Node* node);
isAnchor()112     bool isAnchor() const { return mType == ANCHOR_CACHEDNODETYPE; }
isContentEditable()113     bool isContentEditable() const { return mType == CONTENT_EDITABLE_CACHEDNODETYPE; }
isCursor()114     bool isCursor() const { return mIsCursor; }
isArea()115     bool isArea() const { return mType == AREA_CACHEDNODETYPE; }
isFocus()116     bool isFocus() const { return mIsFocus; }
isFrame()117     bool isFrame() const { return mType == FRAME_CACHEDNODETYPE; }
isHidden()118     bool isHidden() const { return mIsHidden; }
isInLayer()119     bool isInLayer() const { return mIsInLayer; }
isNavable(const CachedFrame * frame,const WebCore::IntRect & clip)120     bool isNavable(const CachedFrame* frame, const WebCore::IntRect& clip) const {
121         return clip.intersects(bounds(frame));
122     }
isPlugin()123     bool isPlugin() const { return mType == PLUGIN_CACHEDNODETYPE; }
isSelect()124     bool isSelect() const { return mType == SELECT_CACHEDNODETYPE; }
isSyntheticLink()125     bool isSyntheticLink() const {
126         return mType >= ADDRESS_CACHEDNODETYPE && mType <= PHONE_CACHEDNODETYPE;
127     }
128     bool isTextField(const CachedFrame*) const;
isTextInput()129     bool isTextInput() const { return mType == TEXT_INPUT_CACHEDNODETYPE; }
isTransparent()130     bool isTransparent() const { return mIsTransparent; }
isUnclipped()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);
navableRects()139     int navableRects() const { return mNavableRects; }
nodePointer()140     void* nodePointer() const { return mNode; }
noSecondChance()141     bool noSecondChance() const { return mCondition > SECOND_CHANCE_END; }
originalAbsoluteBounds()142     const WebCore::IntRect& originalAbsoluteBounds() const {
143         return mOriginalAbsoluteBounds; }
parent()144     const CachedNode* parent() const { return document() + mParentIndex; }
parentGroup()145     void* parentGroup() const { return mParentGroup; }
parentIndex()146     int parentIndex() const { return mParentIndex; }
147     bool partRectsContains(const CachedNode* other) const;
rawBounds()148     const WebCore::IntRect& rawBounds() const { return mBounds; }
149     void reset();
150     WebCore::IntRect ring(const CachedFrame* , size_t part) const;
rings()151     const WTF::Vector<WebCore::IntRect>& rings() const { return mCursorRing; }
setBounds(const WebCore::IntRect & bounds)152     void setBounds(const WebCore::IntRect& bounds) { mBounds = bounds; }
setClippedOut(bool clipped)153     void setClippedOut(bool clipped) { mClippedOut = clipped; }
setColorIndex(int index)154     void setColorIndex(int index) { mColorIndex = index; }
setCondition(Condition condition)155     void setCondition(Condition condition) const { mCondition = condition; }
setDataIndex(int index)156     void setDataIndex(int index) { mDataIndex = index; }
setDisabled(bool disabled)157     void setDisabled(bool disabled) { mDisabled = disabled; }
setExport(const WTF::String & exported)158     void setExport(const WTF::String& exported) { mExport = exported; }
setHasCursorRing(bool hasRing)159     void setHasCursorRing(bool hasRing) { mHasCursorRing = hasRing; }
setHasMouseOver(bool hasMouseOver)160     void setHasMouseOver(bool hasMouseOver) { mHasMouseOver = hasMouseOver; }
setHitBounds(const WebCore::IntRect & bounds)161     void setHitBounds(const WebCore::IntRect& bounds) { mHitBounds = bounds; }
setOriginalAbsoluteBounds(const WebCore::IntRect & bounds)162     void setOriginalAbsoluteBounds(const WebCore::IntRect& bounds) {
163         mOriginalAbsoluteBounds = bounds; }
setIndex(int index)164     void setIndex(int index) { mIndex = index; }
setIsCursor(bool isCursor)165     void setIsCursor(bool isCursor) { mIsCursor = isCursor; }
setIsFocus(bool isFocus)166     void setIsFocus(bool isFocus) { mIsFocus = isFocus; }
setIsInLayer(bool isInLayer)167     void setIsInLayer(bool isInLayer) { mIsInLayer = isInLayer; }
setIsParentAnchor(bool isAnchor)168     void setIsParentAnchor(bool isAnchor) { mIsParentAnchor = isAnchor; }
setIsTransparent(bool isTransparent)169     void setIsTransparent(bool isTransparent) { mIsTransparent = isTransparent; }
setIsUnclipped(bool unclipped)170     void setIsUnclipped(bool unclipped) { mIsUnclipped = unclipped; }
setLast()171     void setLast() { mLast = true; }
setNavableRects()172     void setNavableRects() { mNavableRects = mCursorRing.size(); }
setParentGroup(void * group)173     void setParentGroup(void* group) { mParentGroup = group; }
setParentIndex(int parent)174     void setParentIndex(int parent) { mParentIndex = parent; }
setSingleImage(bool single)175     void setSingleImage(bool single) { mSingleImage = single; }
setTabIndex(int index)176     void setTabIndex(int index) { mTabIndex = index; }
setType(CachedNodeType type)177     void setType(CachedNodeType type) { mType = type; }
show()178     void show() { mIsHidden = false; }
singleImage()179     bool singleImage() const { return mSingleImage; }
tabIndex()180     int tabIndex() const { return mTabIndex; }
textInputIndex()181     int textInputIndex() const { return isTextInput() ? mDataIndex : -1; }
traverseNextNode()182     const CachedNode* traverseNextNode() const { return mLast ? NULL : &this[1]; }
useBounds()183     bool useBounds() const { return mUseBounds; }
useHitBounds()184     bool useHitBounds() const { return mUseHitBounds; }
wantsKeyEvents()185     bool wantsKeyEvents() const { return isTextInput() || isPlugin()
186         || isContentEditable() || isFrame(); }
187 private:
188     friend class CacheBuilder;
189     WTF::String mExport;
190     WebCore::IntRect mBounds;
191     WebCore::IntRect mHitBounds;
192     WebCore::IntRect mOriginalAbsoluteBounds;
193     WTF::Vector<WebCore::IntRect> mCursorRing;
194     void* mNode; // WebCore::Node*, only used to match pointers
195     void* mParentGroup; // WebCore::Node*, only used to match pointers
196     int mDataIndex; // child frame if a frame; input data index; or -1
197     int mIndex; // index of itself, to find first in array (document)
198     int mNavableRects; // FIXME: could be bitfield once I limit max number of rects
199     int mParentIndex;
200     int mTabIndex;
201     int mColorIndex; // index to ring color and other stylable properties
202     mutable Condition mCondition : 5; // why the node was not chosen on the first pass
203     CachedNodeType mType : 4;
204     bool mClippedOut : 1;
205     bool mDisabled : 1;
206     bool mFixedUpCursorRects : 1;
207     bool mHasCursorRing : 1;
208     bool mHasMouseOver : 1;
209     bool mIsCursor : 1;
210     bool mIsFocus : 1;
211     bool mIsHidden : 1;
212     bool mIsInLayer : 1;
213     bool mIsParentAnchor : 1;
214     bool mIsTransparent : 1;
215     bool mIsUnclipped : 1;
216     bool mLast : 1;             // true if this is the last node in a group
217     bool mSingleImage : 1;
218     bool mUseBounds : 1;
219     bool mUseHitBounds : 1;
220 #ifdef BROWSER_DEBUG
221 public:
webCoreNode()222     WebCore::Node* webCoreNode() const { return (WebCore::Node*) mNode; }
223     bool mDisplayMeasure;
224     mutable bool mInCompare;
225     int mSideDistance;
226     int mSecondSide;
227 #endif
228 #if DEBUG_NAV_UI || DUMP_NAV_CACHE
229 public:
230     class Debug {
231 public:
232         CachedNode* base() const;
233         const char* condition(Condition t) const;
234         void print() const;
235         const char* type(CachedNodeType t) const;
236 #if DUMP_NAV_CACHE
237         int mNodeIndex;
238         int mParentGroupIndex;
239 #endif
240     } mDebug;
241     friend class CachedNode::Debug;
242 #endif
243 };
244 
245 }
246 
247 #endif
248