| /* |
| * Copyright 2006, The Android Open Source Project |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef CacheBuilder_H |
| #define CacheBuilder_H |
| |
| #include "CachedDebug.h" |
| #include "CachedNodeType.h" |
| #include "IntRect.h" |
| #include "PlatformString.h" |
| #include "TextDirection.h" |
| #include "wtf/Vector.h" |
| |
| #define NAVIGATION_MAX_PHONE_LENGTH 14 |
| |
| using namespace WebCore; |
| |
| namespace WebCore { |
| |
| class AtomicString; |
| class Document; |
| class Frame; |
| class HTMLAreaElement; |
| class InlineTextBox; |
| class LayerAndroid; |
| class Node; |
| class PlatformGraphicsContext; |
| class RenderFlow; |
| class RenderObject; |
| class RenderLayer; |
| class Text; |
| |
| } |
| |
| namespace android { |
| |
| class CachedFrame; |
| class CachedNode; |
| class CachedRoot; |
| |
| class CacheBuilder { |
| public: |
| enum Direction { |
| UNINITIALIZED = -1, |
| LEFT, |
| RIGHT, |
| UP, |
| DOWN, |
| DIRECTION_COUNT, |
| UP_DOWN = UP & DOWN, // mask and result |
| RIGHT_DOWN = RIGHT & DOWN, // mask and result |
| }; |
| enum FoundState { |
| FOUND_NONE, |
| FOUND_PARTIAL, |
| FOUND_COMPLETE |
| }; |
| CacheBuilder(); |
| void allowAllTextDetection() { mAllowableTypes = ALL_CACHEDNODE_BITS; } |
| void buildCache(CachedRoot* root); |
| static bool ConstructPartRects(Node* node, const IntRect& bounds, |
| IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result); |
| Node* currentFocus() const; |
| void disallowAddressDetection() { mAllowableTypes = (CachedNodeBits) ( |
| mAllowableTypes & ~ADDRESS_CACHEDNODE_BIT); } |
| void disallowEmailDetection() { mAllowableTypes = (CachedNodeBits) ( |
| mAllowableTypes & ~EMAIL_CACHEDNODE_BIT); } |
| void disallowPhoneDetection() { mAllowableTypes = (CachedNodeBits) ( |
| mAllowableTypes & ~PHONE_CACHEDNODE_BIT); } |
| static FoundState FindAddress(const UChar* , unsigned length, int* start, |
| int* end, bool caseInsensitive); |
| static IntRect getAreaRect(const HTMLAreaElement* area); |
| static void GetGlobalOffset(Frame* , int* x, int * y); |
| static void GetGlobalOffset(Node* , int* x, int * y); |
| static bool validNode(Frame* startFrame, void* framePtr, void* nodePtr); |
| private: |
| enum AddressProgress { |
| NO_ADDRESS, |
| SKIP_TO_SPACE, |
| HOUSE_NUMBER, |
| NUMBER_TRAILING_SPACE, |
| ADDRESS_LINE, |
| STATE_NAME, |
| SECOND_HALF, |
| ZIP_CODE, |
| PLUS_4, |
| FIND_STREET |
| }; |
| struct NodeWalk { |
| NodeWalk() { reset(); } |
| int mStart; |
| int mEnd; |
| Node* mFinalNode; |
| InlineTextBox* mLastInline; |
| bool mMore; |
| void reset() { mMore = false; } |
| }; |
| struct BoundsPart { |
| IntRect mRect; |
| int mStart; |
| int mEnd; |
| }; |
| struct Bounds { |
| typedef bool (*FindText)(BoundsPart* result, InlineTextBox* , const String& match); |
| IntRect mNodeBounds; |
| BoundsPart mPart; |
| WTF::Vector<BoundsPart> mParts; |
| char mStore[NAVIGATION_MAX_PHONE_LENGTH + 1]; |
| int mPartIndex; |
| Node* mNode; |
| Node* mFinalNode; |
| void reset() { mNode = NULL; } |
| }; |
| struct FindState { |
| int mStartResult; |
| int mEndResult; |
| const UChar* mCurrentStart; |
| const UChar* mEnd; |
| AddressProgress mProgress; |
| int mNumberCount; |
| int mLetterCount; |
| unsigned mWordCount; |
| int mLineCount; |
| const UChar* mFirstLower; |
| const UChar* mZipStart; |
| const UChar* mBases[16]; // FIXME: random guess, maybe too small, maybe too big |
| const UChar* mWords[16]; |
| const UChar* mEnds[16]; |
| const UChar* mStarts[16]; // text is not necessarily contiguous |
| const char* mStates; |
| int mEndWord; |
| int mStateWord; |
| int mZipHint; |
| int mSectionLength; |
| unsigned mNumberWords; // must contain as many bits as mWords contains elements |
| char* mPattern; |
| UChar mStore[NAVIGATION_MAX_PHONE_LENGTH + 1]; |
| UChar* mStorePtr; |
| UChar mBackOne; |
| UChar mBackTwo; |
| UChar mCurrent; |
| bool mUnparsed; |
| bool mZipDelimiter; |
| bool mOpenParen; |
| bool mInitialized; |
| bool mContinuationNode; |
| bool mCaseInsensitive; |
| void shiftWords(int shift) { |
| memmove(mBases, &mBases[shift], (sizeof(mBases) / |
| sizeof(mBases[0]) - shift) * sizeof(mBases[0])); |
| memmove(mWords, &mWords[shift], (sizeof(mWords) / |
| sizeof(mWords[0]) - shift) * sizeof(mWords[0])); |
| memmove(mEnds, &mEnds[shift], (sizeof(mEnds) / |
| sizeof(mEnds[0]) - shift) * sizeof(mEnds[0])); |
| memmove(mStarts, &mStarts[shift], (sizeof(mStarts) / |
| sizeof(mStarts[0]) - shift) * sizeof(mStarts[0])); |
| } |
| void newWord(const UChar* baseChars, const UChar* chars) { |
| mBases[mWordCount] = baseChars; |
| mWords[mWordCount] = chars; |
| mEnds[mWordCount] = mEnd; |
| mStarts[mWordCount] = mCurrentStart; |
| } |
| }; |
| struct Tracker { |
| Node* mLastChild; |
| }; |
| struct ClipColumnTracker : Tracker { |
| Node* mNode; |
| IntRect mBounds; |
| WTF::Vector<IntRect>* mColumns; |
| int mColumnGap; |
| TextDirection mDirection; |
| bool mHasClip; |
| }; |
| struct LayerTracker : Tracker { |
| LayerAndroid* mLayer; |
| IntRect mBounds; |
| }; |
| struct TabIndexTracker : Tracker { |
| int mTabIndex; |
| }; |
| struct FocusTracker : TabIndexTracker { |
| int mCachedNodeIndex; |
| bool mSomeParentTakesFocus; |
| }; |
| void adjustForColumns(const ClipColumnTracker& track, |
| CachedNode* node, IntRect* bounds); |
| static bool AddPartRect(IntRect& bounds, int x, int y, |
| WTF::Vector<IntRect>* result, IntRect* focusBounds); |
| static bool AnyIsClick(Node* node); |
| static bool AnyChildIsClick(Node* node); |
| static bool NodeHasEventListeners(Node* node, AtomicString* eventTypes, int length); |
| void BuildFrame(Frame* root, Frame* frame, |
| CachedRoot* cachedRoot, CachedFrame* cachedFrame); |
| bool CleanUpContainedNodes(CachedFrame* cachedFrame, |
| const FocusTracker* last, int lastChildIndex); |
| static bool ConstructTextRect(Text* textNode, |
| InlineTextBox* textBox, int start, int relEnd, int x, int y, |
| IntRect* focusBounds, const IntRect& clip, WTF::Vector<IntRect>* result); |
| static bool ConstructTextRects(Text* node, int start, |
| Text* last, int end, int x, int y, IntRect* focusBounds, |
| const IntRect& clip, WTF::Vector<IntRect>* result); |
| static FoundState FindPartialAddress(const UChar* , const UChar* , unsigned length, FindState* ); |
| static FoundState FindPartialEMail(const UChar* , unsigned length, FindState* ); |
| static FoundState FindPartialNumber(const UChar* , unsigned length, FindState* ); |
| static FoundState FindPhoneNumber(const UChar* chars, unsigned length, int* start, int* end); |
| static void FindReset(FindState* ); |
| static void FindResetNumber(FindState* ); |
| static Frame* FrameAnd(CacheBuilder* focusNav); |
| static Frame* FrameAnd(const CacheBuilder* focusNav); |
| static CacheBuilder* Builder(Frame* ); |
| static Frame* HasFrame(Node* ); |
| static bool HasOverOrOut(Node* ); |
| static bool HasTriggerEvent(Node* ); |
| static bool IsDomainChar(UChar ch); |
| bool isFocusableText(NodeWalk* , bool oldMore, Node* , CachedNodeType* type, |
| String* exported) const; //returns true if it is focusable |
| static bool IsMailboxChar(UChar ch); |
| static bool IsRealNode(Frame* , Node* ); |
| int overlap(int left, int right); // returns distance scale factor as 16.16 scalar |
| bool setData(CachedFrame* ); |
| #if USE(ACCELERATED_COMPOSITING) |
| void TrackLayer(WTF::Vector<LayerTracker>& layerTracker, |
| RenderObject* nodeRenderer, Node* lastChild); |
| #endif |
| Node* tryFocus(Direction direction); |
| Node* trySegment(Direction direction, int mainStart, int mainEnd); |
| CachedNodeBits mAllowableTypes; |
| #if DUMP_NAV_CACHE |
| public: |
| class Debug { |
| public: |
| void frameName(char*& namePtr, const char* max) const; |
| void init(char* buffer, size_t size); |
| static int ParentIndex(Node* node, int count, Node* parent); |
| void print() { frames(); } |
| void print(const char* name); |
| void wideString(const String& str); |
| private: |
| void attr(const AtomicString& name, const AtomicString& value); |
| void comma(const char* str); |
| void flush(); |
| Frame* frameAnd() const; |
| void frames(); |
| void groups(); |
| bool isFocusable(Node* node); |
| void localName(Node* node); |
| void newLine(int indent = 0); |
| void print(const char* name, unsigned len); |
| void setIndent(int ); |
| void uChar(const UChar* name, unsigned len, bool hex); |
| void validateFrame(); |
| void validateStringData(); |
| void wideString(const UChar* chars, int length, bool hex); |
| char* mBuffer; |
| size_t mBufferSize; |
| int mIndex; |
| const char* mPrefix; |
| int mMinPrefix; |
| } mDebug; |
| #endif |
| }; |
| |
| } |
| |
| #endif |