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