Home | History | Annotate | Download | only in nav
      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     };
     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;
     91     int childFrameIndex() const { return isFrame() ? mDataIndex : -1; }
     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& );
     97     bool clippedOut() { return mClippedOut; }
     98     WebCore::IntRect cursorRingBounds(const CachedFrame* ) const;
     99     void cursorRings(const CachedFrame* , WTF::Vector<WebCore::IntRect>* ) const;
    100     bool disabled() const { return mDisabled; }
    101     const CachedNode* document() const { return &this[-mIndex]; }
    102     void fixUpCursorRects(const CachedFrame* frame);
    103     const WebCore::String& getExport() const { return mExport; }
    104     bool hasCursorRing() const { return mHasCursorRing; }
    105     bool hasMouseOver() const { return mHasMouseOver; }
    106     void hideCursor(CachedFrame* );
    107     WebCore::IntRect hitBounds(const CachedFrame* ) const;
    108     int index() const { return mIndex; }
    109     void init(WebCore::Node* node);
    110     bool isAnchor() const { return mType == ANCHOR_CACHEDNODETYPE; }
    111     bool isCursor() const { return mIsCursor; }
    112     bool isArea() const { return mType == AREA_CACHEDNODETYPE; }
    113     bool isFocus() const { return mIsFocus; }
    114     bool isFrame() const { return mType == FRAME_CACHEDNODETYPE; }
    115     bool isHidden() const { return mIsHidden; }
    116     bool isInLayer() const { return mIsInLayer; }
    117     bool isNavable(const CachedFrame* frame, const WebCore::IntRect& clip) const {
    118         return clip.intersects(bounds(frame));
    119     }
    120     bool isPlugin() const { return mType == PLUGIN_CACHEDNODETYPE; }
    121     bool isSyntheticLink() const {
    122         return mType >= ADDRESS_CACHEDNODETYPE && mType <= PHONE_CACHEDNODETYPE;
    123     }
    124     bool isTextField(const CachedFrame*) const;
    125     bool isTextInput() const { return mType == TEXT_INPUT_CACHEDNODETYPE; }
    126     bool isTransparent() const { return mIsTransparent; }
    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);
    135     int navableRects() const { return mNavableRects; }
    136     void* nodePointer() const { return mNode; }
    137     bool noSecondChance() const { return mCondition > SECOND_CHANCE_END; }
    138     const WebCore::IntRect& originalAbsoluteBounds() const {
    139         return mOriginalAbsoluteBounds; }
    140     const CachedNode* parent() const { return document() + mParentIndex; }
    141     void* parentGroup() const { return mParentGroup; }
    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;
    146     void setBounds(const WebCore::IntRect& bounds) { mBounds = bounds; }
    147     void setClippedOut(bool clipped) { mClippedOut = clipped; }
    148     void setCondition(Condition condition) const { mCondition = condition; }
    149     void setDataIndex(int index) { mDataIndex = index; }
    150     void setDisabled(bool disabled) { mDisabled = disabled; }
    151     void setExport(const WebCore::String& exported) { mExport = exported; }
    152     void setHasCursorRing(bool hasRing) { mHasCursorRing = hasRing; }
    153     void setHasMouseOver(bool hasMouseOver) { mHasMouseOver = hasMouseOver; }
    154     void setHitBounds(const WebCore::IntRect& bounds) { mHitBounds = bounds; }
    155     void setOriginalAbsoluteBounds(const WebCore::IntRect& bounds) {
    156         mOriginalAbsoluteBounds = bounds; }
    157     void setIndex(int index) { mIndex = index; }
    158     void setIsCursor(bool isCursor) { mIsCursor = isCursor; }
    159     void setIsFocus(bool isFocus) { mIsFocus = isFocus; }
    160     void setIsInLayer(bool isInLayer) { mIsInLayer = isInLayer; }
    161     void setIsParentAnchor(bool isAnchor) { mIsParentAnchor = isAnchor; }
    162     void setIsTransparent(bool isTransparent) { mIsTransparent = isTransparent; }
    163     void setIsUnclipped(bool unclipped) { mIsUnclipped = unclipped; }
    164     void setLast() { mLast = true; }
    165     void setNavableRects() { mNavableRects = mCursorRing.size(); }
    166     void setParentGroup(void* group) { mParentGroup = group; }
    167     void setParentIndex(int parent) { mParentIndex = parent; }
    168     void setTabIndex(int index) { mTabIndex = index; }
    169     void setType(CachedNodeType type) { mType = type; }
    170     void show() { mIsHidden = false; }
    171     int tabIndex() const { return mTabIndex; }
    172     int textInputIndex() const { return isTextInput() ? mDataIndex : -1; }
    173     const CachedNode* traverseNextNode() const { return mLast ? NULL : &this[1]; }
    174     bool useBounds() const { return mUseBounds; }
    175     bool useHitBounds() const { return mUseHitBounds; }
    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:
    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