2 * Copyright 2007, The Android Open Source Project
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "CachedInput.h"
30 #include "CachedLayer.h"
31 #include "CachedNode.h"
34 #include "wtf/Vector.h"
48 // first node referenced by cache is always document
58 DIRECTION_MASK = DIRECTION_COUNT - 1,
59 UP_DOWN = UP & DOWN, // mask and result
60 RIGHT_DOWN = RIGHT & DOWN, // mask and result
68 CURSOR_UNINITIALIZED = -2,
73 void add(CachedInput& input) { mCachedTextInputs.append(input); }
74 #if USE(ACCELERATED_COMPOSITING)
75 void add(CachedLayer& layer) { mCachedLayers.append(layer); }
77 void add(CachedNode& node) { mCachedNodes.append(node); }
78 void addFrame(CachedFrame& child) { mCachedFrames.append(child); }
79 WebCore::IntRect adjustBounds(const CachedNode* ,
80 const WebCore::IntRect& ) const;
81 bool checkRings(const CachedNode* node,
82 const WTF::Vector<WebCore::IntRect>& rings,
83 const WebCore::IntRect& bounds) const;
84 bool checkVisited(const CachedNode* , CachedFrame::Direction ) const;
85 size_t childCount() { return mCachedFrames.size(); }
87 const CachedNode* currentCursor() const { return currentCursor(NULL); }
88 const CachedNode* currentCursor(const CachedFrame** ) const;
89 const CachedNode* currentFocus() const { return currentFocus(NULL); }
90 const CachedNode* currentFocus(const CachedFrame** ) const;
91 bool directionChange() const;
92 const CachedNode* document() const { return mCachedNodes.begin(); }
93 bool empty() const { return mCachedNodes.size() < 2; } // must have 1 past doc
94 const CachedNode* findBestAt(const WebCore::IntRect& , int* best,
95 bool* inside, const CachedNode** , const CachedFrame** , int* x,
96 int* y, bool checkForHidden) const;
97 const CachedFrame* findBestFrameAt(int x, int y) const;
98 const CachedNode* findBestHitAt(const WebCore::IntRect& ,
99 const CachedFrame** , int* x, int* y) const;
101 CachedFrame* firstChild() { return mCachedFrames.begin(); }
102 const CachedFrame* firstChild() const { return mCachedFrames.begin(); }
103 void* framePointer() const { return mFrame; }
104 CachedNode* getIndex(int index) { return index >= 0 ?
105 &mCachedNodes[index] : NULL; }
106 const CachedFrame* hasFrame(const CachedNode* node) const;
108 int indexInParent() const { return mIndexInParent; }
109 void init(const CachedRoot* root, int index, WebCore::Frame* frame);
110 const CachedFrame* lastChild() const { return &mCachedFrames.last(); }
111 CachedNode* lastNode() { return &mCachedNodes.last(); }
112 CachedFrame* lastChild() { return &mCachedFrames.last(); }
113 #if USE(ACCELERATED_COMPOSITING)
114 const CachedLayer* layer(const CachedNode* ) const;
117 * Find the next textfield/textarea
118 * @param start Must be a CachedNode in this CachedFrame's tree, or
119 * null, in which case we start from the beginning.
120 * @param framePtr If not null, and a textfield/textarea is found, its
121 * CachedFrame will be pointed to by this pointer.
122 * @param includeTextAreas If true, will return the next textfield or area.
123 * Otherwise it only considers textfields.
124 * @return CachedNode* Next textfield (or area)
126 const CachedNode* nextTextField(const CachedNode* start,
127 const CachedFrame** framePtr, bool includeTextAreas) const;
128 const CachedFrame* parent() const { return mParent; }
129 CachedFrame* parent() { return mParent; }
130 SkPicture* picture(const CachedNode* ) const;
132 bool sameFrame(const CachedFrame* ) const;
133 void removeLast() { mCachedNodes.removeLast(); }
134 void resetClippedOut();
135 void setContentsSize(int width, int height) { mContents.setWidth(width);
136 mContents.setHeight(height); }
137 bool setCursor(WebCore::Frame* , WebCore::Node* , int x, int y);
138 void setCursorIndex(int index) { mCursorIndex = index; }
140 bool setFocus(WebCore::Frame* , WebCore::Node* , int x, int y);
141 void setFocusIndex(int index) { mFocusIndex = index; }
142 void setLocalViewBounds(const WebCore::IntRect& bounds) { mLocalViewBounds = bounds; }
143 int size() { return mCachedNodes.size(); }
144 const CachedInput* textInput(const CachedNode* node) const {
145 return node->isTextInput() ? &mCachedTextInputs[node->textInputIndex()]
148 const CachedNode* validDocument() const;
153 int mMajorDelta; // difference of center of object
154 // used only when leading and trailing edges contain another set of edges
155 int mMajorDelta2; // difference of leading edge (only used when center is same)
156 int mMajorButt; // checks for next cell butting up against or close to previous one
161 const CachedFrame* mFrame;
162 const CachedNode* mNode;
163 SkFixed mWorkingOverlap; // this and below are fuzzy answers instead of bools
169 bool mWorkingOutside;
170 int bottom() const { return bounds().bottom(); }
171 const WebCore::IntRect& bounds() const { return mNodeBounds; }
172 bool canBeReachedByAnotherDirection();
173 int height() const { return bounds().height(); }
174 bool inOrSubsumesNav() const { return (mNavDelta ^ mNavDelta2) >= 0; }
175 bool inOrSubsumesWorking() const { return (mWorkingDelta ^ mWorkingDelta2) >= 0; }
176 int isContainer(BestData* );
177 const WebCore::IntRect& mouseBounds() const { return mMouseBounds; }
178 static SkFixed Overlap(int span, int left, int right);
179 void reset() { mNode = NULL; }
180 int right() const { return bounds().right(); }
181 void setMouseBounds(const WebCore::IntRect& b) { mMouseBounds = b; }
182 void setNodeBounds(const WebCore::IntRect& b) { mNodeBounds = b; }
184 bool setDownDirection(const CachedHistory* );
185 bool setLeftDirection(const CachedHistory* );
186 bool setRightDirection(const CachedHistory* );
187 bool setUpDirection(const CachedHistory* );
188 void setNavInclusion(int left, int right);
189 void setNavOverlap(int span, int left, int right);
190 void setWorkingInclusion(int left, int right);
191 void setWorkingOverlap(int span, int left, int right);
192 int width() const { return bounds().width(); }
193 int x() const { return bounds().x(); }
194 int y() const { return bounds().y(); }
195 private: // since computing these is complicated, protect them so that the
196 // are only written by appropriate helpers
197 WebCore::IntRect mMouseBounds;
198 WebCore::IntRect mNodeBounds;
200 typedef const CachedNode* (CachedFrame::*MoveInDirection)(
201 const CachedNode* test, const CachedNode* limit, BestData* ) const;
202 void adjustToTextColumn(int* delta) const;
203 static bool CheckBetween(Direction , const WebCore::IntRect& bestRect,
204 const WebCore::IntRect& prior, WebCore::IntRect* result);
205 bool checkBetween(BestData* , Direction );
206 int compare(BestData& testData, const BestData& bestData) const;
207 void findClosest(BestData* , Direction original, Direction test,
208 WebCore::IntRect* clip) const;
209 int frameNodeCommon(BestData& testData, const CachedNode* test,
210 BestData* bestData, BestData* originalData) const;
211 int framePartCommon(BestData& testData, const CachedNode* test,
213 const CachedNode* frameDown(const CachedNode* test, const CachedNode* limit,
215 const CachedNode* frameLeft(const CachedNode* test, const CachedNode* limit,
217 const CachedNode* frameRight(const CachedNode* test, const CachedNode* limit,
219 const CachedNode* frameUp(const CachedNode* test, const CachedNode* limit,
221 int minWorkingHorizontal() const;
222 int minWorkingVertical() const;
223 int maxWorkingHorizontal() const;
224 int maxWorkingVertical() const;
225 bool moveInFrame(MoveInDirection , const CachedNode* test, BestData* ) const;
226 const WebCore::IntRect& _navBounds() const;
227 WebCore::IntRect mContents;
228 WebCore::IntRect mLocalViewBounds;
229 WebCore::IntRect mViewBounds;
230 WTF::Vector<CachedNode> mCachedNodes;
231 WTF::Vector<CachedFrame> mCachedFrames;
232 WTF::Vector<CachedInput> mCachedTextInputs;
233 #if USE(ACCELERATED_COMPOSITING)
234 WTF::Vector<CachedLayer> mCachedLayers;
236 void* mFrame; // WebCore::Frame*, used only to compare pointers
237 CachedFrame* mParent;
240 int mIndexInParent; // index within parent's array of children, or -1 if root
241 const CachedRoot* mRoot;
243 CachedHistory* history() const;
246 CachedNode* find(WebCore::Node* ); // !!! probably debugging only
248 int mDebugLoopbackOffset;
250 #if !defined NDEBUG || DUMP_NAV_CACHE
256 mFrameName[0] = '\0';
263 ~Debug() { mInUse = false; }
267 CachedFrame* base() const;
269 bool validate(const CachedNode* ) const;
270 char mFrameName[256];