Home | History | Annotate | Download | only in nav
      1 /*
      2  * Copyright 2006, 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 CacheBuilder_h
     27 #define CacheBuilder_h
     28 
     29 #include "CachedDebug.h"
     30 #include "CachedNodeType.h"
     31 #include "IntRect.h"
     32 #include "PlatformString.h"
     33 #include "TextDirection.h"
     34 #include <wtf/Forward.h>
     35 #include <wtf/Vector.h>
     36 
     37 #define NAVIGATION_MAX_PHONE_LENGTH 14
     38 
     39 using namespace WebCore;
     40 
     41 namespace WebCore {
     42 
     43 class ColumnInfo;
     44 class Document;
     45 class Frame;
     46 class HTMLAreaElement;
     47 class InlineTextBox;
     48 class LayerAndroid;
     49 class Node;
     50 class PlatformGraphicsContext;
     51 class RenderBlock;
     52 class RenderFlow;
     53 class RenderLayer;
     54 class RenderObject;
     55 class Text;
     56 
     57 }
     58 
     59 namespace android {
     60 
     61 class CachedFrame;
     62 class CachedNode;
     63 class CachedRoot;
     64 
     65 class CacheBuilder {
     66 public:
     67     enum Direction {
     68         UNINITIALIZED = -1,
     69         LEFT,
     70         RIGHT,
     71         UP,
     72         DOWN,
     73         DIRECTION_COUNT,
     74         UP_DOWN = UP & DOWN,  // mask and result
     75         RIGHT_DOWN = RIGHT & DOWN, // mask and result
     76     };
     77     enum FoundState {
     78         FOUND_NONE,
     79         FOUND_PARTIAL,
     80         FOUND_COMPLETE
     81     };
     82     CacheBuilder();
     83     void allowAllTextDetection() { mAllowableTypes = ALL_CACHEDNODE_BITS; }
     84     void buildCache(CachedRoot* root);
     85     static bool ConstructPartRects(Node* node, const IntRect& bounds,
     86         IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result,
     87         int* imageCountPtr);
     88     Node* currentFocus() const;
     89     void disallowAddressDetection() { mAllowableTypes = (CachedNodeBits) (
     90         mAllowableTypes & ~ADDRESS_CACHEDNODE_BIT); }
     91     void disallowEmailDetection() { mAllowableTypes = (CachedNodeBits) (
     92         mAllowableTypes & ~EMAIL_CACHEDNODE_BIT); }
     93     void disallowPhoneDetection() { mAllowableTypes = (CachedNodeBits) (
     94         mAllowableTypes & ~PHONE_CACHEDNODE_BIT); }
     95     static FoundState FindAddress(const UChar* , unsigned length, int* start,
     96         int* end, bool caseInsensitive);
     97     static IntRect getAreaRect(const HTMLAreaElement* area);
     98     static void GetGlobalOffset(Frame* , int* x, int * y);
     99     static void GetGlobalOffset(Node* , int* x, int * y);
    100     bool pictureSetDisabled() { return mPictureSetDisabled; }
    101     static bool validNode(Frame* startFrame, void* framePtr, void* nodePtr);
    102 private:
    103     enum AddressProgress {
    104         NO_ADDRESS,
    105         SKIP_TO_SPACE,
    106         HOUSE_NUMBER,
    107         NUMBER_TRAILING_SPACE,
    108         ADDRESS_LINE,
    109         STATE_NAME,
    110         SECOND_HALF,
    111         ZIP_CODE,
    112         PLUS_4,
    113         FIND_STREET
    114     };
    115     struct NodeWalk {
    116         NodeWalk() { reset(); }
    117         int mStart;
    118         int mEnd;
    119         Node* mFinalNode;
    120         InlineTextBox* mLastInline;
    121         bool mMore;
    122         void reset() { mMore = false; }
    123     };
    124     struct BoundsPart {
    125         IntRect mRect;
    126         int mStart;
    127         int mEnd;
    128     };
    129     struct Bounds {
    130         typedef bool (*FindText)(BoundsPart* result, InlineTextBox* , const String& match);
    131         IntRect mNodeBounds;
    132         BoundsPart mPart;
    133         WTF::Vector<BoundsPart> mParts;
    134         char mStore[NAVIGATION_MAX_PHONE_LENGTH + 1];
    135         int mPartIndex;
    136         Node* mNode;
    137         Node* mFinalNode;
    138         void reset() { mNode = NULL; }
    139     };
    140     struct FindState {
    141         int mStartResult;
    142         int mEndResult;
    143         const UChar* mCurrentStart;
    144         const UChar* mEnd;
    145         AddressProgress mProgress;
    146         int mNumberCount;
    147         int mLetterCount;
    148         unsigned mWordCount;
    149         int mLineCount;
    150         const UChar* mFirstLower;
    151         const UChar* mZipStart;
    152         const UChar* mBases[16]; // FIXME: random guess, maybe too small, maybe too big
    153         const UChar* mWords[16];
    154         const UChar* mEnds[16];
    155         const UChar* mStarts[16]; // text is not necessarily contiguous
    156         const char* mStates;
    157         int mEndWord;
    158         int mStateWord;
    159         int mZipHint;
    160         int mSectionLength;
    161         unsigned mNumberWords; // must contain as many bits as mWords contains elements
    162         char* mPattern;
    163         UChar mStore[NAVIGATION_MAX_PHONE_LENGTH + 1];
    164         UChar* mStorePtr;
    165         UChar mBackOne;
    166         UChar mBackTwo;
    167         UChar mCurrent;
    168         bool mUnparsed;
    169         bool mZipDelimiter;
    170         bool mOpenParen;
    171         bool mInitialized;
    172         bool mContinuationNode;
    173         bool mCaseInsensitive;
    174         void shiftWords(int shift) {
    175             memmove(mBases, &mBases[shift], (sizeof(mBases) /
    176                 sizeof(mBases[0]) - shift) * sizeof(mBases[0]));
    177             memmove(mWords, &mWords[shift], (sizeof(mWords) /
    178                 sizeof(mWords[0]) - shift) * sizeof(mWords[0]));
    179             memmove(mEnds, &mEnds[shift], (sizeof(mEnds) /
    180                 sizeof(mEnds[0]) - shift) * sizeof(mEnds[0]));
    181             memmove(mStarts, &mStarts[shift], (sizeof(mStarts) /
    182                 sizeof(mStarts[0]) - shift) * sizeof(mStarts[0]));
    183         }
    184         void newWord(const UChar* baseChars, const UChar* chars) {
    185             mBases[mWordCount] = baseChars;
    186             mWords[mWordCount] = chars;
    187             mEnds[mWordCount] = mEnd;
    188             mStarts[mWordCount] = mCurrentStart;
    189         }
    190     };
    191     struct Tracker {
    192         Node* mLastChild;
    193     };
    194     struct ClipColumnTracker : Tracker {
    195         Node* mNode;
    196         IntRect mBounds;
    197         ColumnInfo* mColumnInfo;
    198         int mColumnGap;
    199         TextDirection mDirection;
    200         bool mHasClip;
    201     };
    202     struct LayerTracker : Tracker {
    203         LayerAndroid* mLayer;
    204         RenderLayer* mRenderLayer;
    205         IntRect mBounds;
    206         IntPoint mScroll;
    207         ~LayerTracker();
    208     };
    209     struct TabIndexTracker : Tracker {
    210         int mTabIndex;
    211     };
    212     struct FocusTracker : TabIndexTracker {
    213         int mCachedNodeIndex;
    214         bool mSomeParentTakesFocus;
    215     };
    216     void adjustForColumns(const ClipColumnTracker& track,
    217         CachedNode* node, IntRect* bounds, RenderBlock*);
    218     static bool AddPartRect(IntRect& bounds, int x, int y,
    219         WTF::Vector<IntRect>* result, IntRect* focusBounds);
    220     static bool AnyIsClick(Node* node);
    221     static bool AnyChildIsClick(Node* node);
    222     static bool NodeHasEventListeners(Node* node, AtomicString* eventTypes, int length);
    223     void BuildFrame(Frame* root, Frame* frame,
    224         CachedRoot* cachedRoot, CachedFrame* cachedFrame);
    225     bool CleanUpContainedNodes(CachedRoot* cachedRoot, CachedFrame* cachedFrame,
    226         const FocusTracker* last, int lastChildIndex);
    227     static bool ConstructTextRect(Text* textNode,
    228         InlineTextBox* textBox, int start, int relEnd, int x, int y,
    229         IntRect* focusBounds, const IntRect& clip, WTF::Vector<IntRect>* result);
    230     static bool ConstructTextRects(Text* node, int start,
    231         Text* last, int end, int x, int y, IntRect* focusBounds,
    232         const IntRect& clip, WTF::Vector<IntRect>* result);
    233     static FoundState FindPartialAddress(const UChar* , const UChar* , unsigned length, FindState* );
    234     static FoundState FindPartialEMail(const UChar* , unsigned length, FindState* );
    235     static FoundState FindPartialNumber(const UChar* , unsigned length, FindState* );
    236     static FoundState FindPhoneNumber(const UChar* chars, unsigned length, int* start, int* end);
    237     static void FindReset(FindState* );
    238     static void FindResetNumber(FindState* );
    239     static Frame* FrameAnd(CacheBuilder* focusNav);
    240     static Frame* FrameAnd(const CacheBuilder* focusNav);
    241     static CacheBuilder* Builder(Frame* );
    242     static Frame* HasFrame(Node* );
    243     static bool HasOverOrOut(Node* );
    244     static bool HasTriggerEvent(Node* );
    245     static bool IsDomainChar(UChar ch);
    246     bool isFocusableText(NodeWalk* , bool oldMore, Node* , CachedNodeType* type,
    247         String* exported) const; //returns true if it is focusable
    248     static bool IsMailboxChar(UChar ch);
    249     static bool IsRealNode(Frame* , Node* );
    250     int overlap(int left, int right); // returns distance scale factor as 16.16 scalar
    251     bool setData(CachedFrame* );
    252 #if USE(ACCELERATED_COMPOSITING)
    253     void TrackLayer(WTF::Vector<LayerTracker>& layerTracker,
    254         RenderObject* nodeRenderer, Node* lastChild, int offsetX, int offsetY);
    255 #endif
    256     Node* tryFocus(Direction direction);
    257     Node* trySegment(Direction direction, int mainStart, int mainEnd);
    258     CachedNodeBits mAllowableTypes;
    259     bool mPictureSetDisabled;
    260 #if DUMP_NAV_CACHE
    261 public:
    262     class Debug {
    263 public:
    264         void frameName(char*& namePtr, const char* max) const;
    265         void init(char* buffer, size_t size);
    266         static int ParentIndex(Node* node, int count, Node* parent);
    267         void print() { frames(); }
    268         void print(const char* name);
    269         void wideString(const String& str);
    270 private:
    271         void attr(const AtomicString& name, const AtomicString& value);
    272         void comma(const char* str);
    273         void flush();
    274         Frame* frameAnd() const;
    275         void frames();
    276         void groups();
    277         bool isFocusable(Node* node);
    278         void localName(Node* node);
    279         void newLine(int indent = 0);
    280         void print(const char* name, unsigned len);
    281         void setIndent(int );
    282         void uChar(const UChar* name, unsigned len, bool hex);
    283         void validateFrame();
    284         void validateStringData();
    285         void wideString(const UChar* chars, int length, bool hex);
    286         char* mBuffer;
    287         size_t mBufferSize;
    288         int mIndex;
    289         const char* mPrefix;
    290         int mMinPrefix;
    291     } mDebug;
    292 #endif
    293 };
    294 
    295 }
    296 
    297 #endif
    298