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