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