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