OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
3 * Copyright (C) 2006 Apple Computer, Inc. | 3 * Copyright (C) 2006 Apple Computer, Inc. |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 * Library General Public License for more details. | 13 * Library General Public License for more details. |
14 * | 14 * |
15 * You should have received a copy of the GNU Library General Public License | 15 * You should have received a copy of the GNU Library General Public License |
16 * along with this library; see the file COPYING.LIB. If not, write to | 16 * along with this library; see the file COPYING.LIB. If not, write to |
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 * Boston, MA 02110-1301, USA. | 18 * Boston, MA 02110-1301, USA. |
19 */ | 19 */ |
20 | 20 |
21 #include "config.h" | 21 #include "config.h" |
22 #include "core/page/FrameTree.h" | 22 #include "core/page/FrameTree.h" |
23 | 23 |
24 #include "core/dom/Document.h" | 24 #include "core/dom/Document.h" |
25 #include "core/frame/FrameClient.h" | 25 #include "core/frame/FrameClient.h" |
26 #include "core/frame/FrameView.h" | 26 #include "core/frame/FrameView.h" |
27 #include "core/frame/LocalFrame.h" | 27 #include "core/frame/LocalFrame.h" |
| 28 #include "core/frame/RemoteFrame.h" |
| 29 #include "core/frame/RemoteFrameView.h" |
28 #include "core/page/Page.h" | 30 #include "core/page/Page.h" |
29 #include "wtf/Vector.h" | 31 #include "wtf/Vector.h" |
30 #include "wtf/text/CString.h" | 32 #include "wtf/text/CString.h" |
31 #include "wtf/text/StringBuilder.h" | 33 #include "wtf/text/StringBuilder.h" |
32 | 34 |
33 using std::swap; | 35 using std::swap; |
34 | 36 |
35 namespace WebCore { | 37 namespace WebCore { |
36 | 38 |
37 namespace { | 39 namespace { |
38 | 40 |
39 const unsigned invalidChildCount = ~0; | 41 const unsigned invalidChildCount = ~0; |
40 | 42 |
41 } // namespace | 43 } // namespace |
42 | 44 |
43 FrameTree::FrameTree(Frame* thisFrame) | 45 FrameTree::FrameTree(Frame* thisFrame) |
44 : m_thisFrame(thisFrame) | 46 : m_thisFrame(thisFrame) |
45 , m_scopedChildCount(invalidChildCount) | 47 , m_scopedChildCount(invalidChildCount) |
46 { | 48 { |
47 } | 49 } |
48 | 50 |
49 FrameTree::~FrameTree() | 51 FrameTree::~FrameTree() |
50 { | 52 { |
51 // FIXME: Why is this here? Doesn't this parallel what we already do in ~Loc
alFrame? | 53 // FIXME: Why is this here? Doesn't this parallel what we already do in ~Loc
alFrame? |
52 for (LocalFrame* child = firstChild(); child; child = child->tree().nextSibl
ing()) | 54 for (Frame* child = firstChild(); child; child = child->tree().nextSibling()
) { |
53 child->setView(nullptr); | 55 if (child->isLocalFrame()) |
| 56 toLocalFrame(child)->setView(nullptr); |
| 57 else if (child->isRemoteFrame()) |
| 58 toRemoteFrame(child)->setView(nullptr); |
| 59 } |
54 } | 60 } |
55 | 61 |
56 void FrameTree::setName(const AtomicString& name, const AtomicString& fallbackNa
me) | 62 void FrameTree::setName(const AtomicString& name, const AtomicString& fallbackNa
me) |
57 { | 63 { |
58 m_name = name; | 64 m_name = name; |
59 if (!parent()) { | 65 if (!parent()) { |
60 m_uniqueName = name; | 66 m_uniqueName = name; |
61 return; | 67 return; |
62 } | 68 } |
63 m_uniqueName = AtomicString(); // Remove our old frame name so it's not cons
idered in uniqueChildName. | 69 m_uniqueName = AtomicString(); // Remove our old frame name so it's not cons
idered in uniqueChildName. |
64 m_uniqueName = parent()->tree().uniqueChildName(name.isEmpty() ? fallbackNam
e : name); | 70 m_uniqueName = parent()->tree().uniqueChildName(name.isEmpty() ? fallbackNam
e : name); |
65 } | 71 } |
66 | 72 |
67 LocalFrame* FrameTree::parent() const | 73 Frame* FrameTree::parent() const |
68 { | 74 { |
69 if (!m_thisFrame->client()) | 75 if (!m_thisFrame->client()) |
70 return 0; | 76 return 0; |
71 // FIXME: Temporary hack to stage converting locations that really should be
Frame. | 77 return m_thisFrame->client()->parent(); |
72 return toLocalFrame(m_thisFrame->client()->parent()); | |
73 } | 78 } |
74 | 79 |
75 LocalFrame* FrameTree::top() const | 80 Frame* FrameTree::top() const |
76 { | 81 { |
77 // FIXME: top() should never return null, so here are some hacks to deal | 82 // FIXME: top() should never return null, so here are some hacks to deal |
78 // with EmptyFrameLoaderClient and cases where the frame is detached | 83 // with EmptyFrameLoaderClient and cases where the frame is detached |
79 // already... | 84 // already... |
80 if (!m_thisFrame->client()) | 85 if (!m_thisFrame->client()) |
81 return toLocalFrame(m_thisFrame); | 86 return m_thisFrame; |
82 // FIXME: Temporary hack to stage converting locations that really should be
Frame. | 87 Frame* candidate = m_thisFrame->client()->top(); |
83 LocalFrame* candidate = toLocalFrame(m_thisFrame->client()->top()); | 88 return candidate ? candidate : m_thisFrame; |
84 return candidate ? candidate : toLocalFrame(m_thisFrame); | |
85 } | 89 } |
86 | 90 |
87 LocalFrame* FrameTree::previousSibling() const | 91 Frame* FrameTree::previousSibling() const |
88 { | 92 { |
89 if (!m_thisFrame->client()) | 93 if (!m_thisFrame->client()) |
90 return 0; | 94 return 0; |
91 // FIXME: Temporary hack to stage converting locations that really should be
Frame. | 95 return m_thisFrame->client()->previousSibling(); |
92 return toLocalFrame(m_thisFrame->client()->previousSibling()); | |
93 } | 96 } |
94 | 97 |
95 LocalFrame* FrameTree::nextSibling() const | 98 Frame* FrameTree::nextSibling() const |
96 { | 99 { |
97 if (!m_thisFrame->client()) | 100 if (!m_thisFrame->client()) |
98 return 0; | 101 return 0; |
99 // FIXME: Temporary hack to stage converting locations that really should be
Frame. | 102 return m_thisFrame->client()->nextSibling(); |
100 return toLocalFrame(m_thisFrame->client()->nextSibling()); | |
101 } | 103 } |
102 | 104 |
103 LocalFrame* FrameTree::firstChild() const | 105 Frame* FrameTree::firstChild() const |
104 { | 106 { |
105 if (!m_thisFrame->client()) | 107 if (!m_thisFrame->client()) |
106 return 0; | 108 return 0; |
107 // FIXME: Temporary hack to stage converting locations that really should be
Frame. | 109 return m_thisFrame->client()->firstChild(); |
108 return toLocalFrame(m_thisFrame->client()->firstChild()); | |
109 } | 110 } |
110 | 111 |
111 LocalFrame* FrameTree::lastChild() const | 112 Frame* FrameTree::lastChild() const |
112 { | 113 { |
113 if (!m_thisFrame->client()) | 114 if (!m_thisFrame->client()) |
114 return 0; | 115 return 0; |
115 // FIXME: Temporary hack to stage converting locations that really should be
Frame. | 116 return m_thisFrame->client()->lastChild(); |
116 return toLocalFrame(m_thisFrame->client()->lastChild()); | |
117 } | 117 } |
118 | 118 |
119 bool FrameTree::uniqueNameExists(const AtomicString& name) const | 119 bool FrameTree::uniqueNameExists(const AtomicString& name) const |
120 { | 120 { |
121 for (LocalFrame* frame = top(); frame; frame = frame->tree().traverseNext())
{ | 121 for (Frame* frame = top(); frame; frame = frame->tree().traverseNext()) { |
122 if (frame->tree().uniqueName() == name) | 122 if (frame->tree().uniqueName() == name) |
123 return true; | 123 return true; |
124 } | 124 } |
125 return false; | 125 return false; |
126 } | 126 } |
127 | 127 |
128 AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const | 128 AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const |
129 { | 129 { |
130 if (!requestedName.isEmpty() && !uniqueNameExists(requestedName) && requeste
dName != "_blank") | 130 if (!requestedName.isEmpty() && !uniqueNameExists(requestedName) && requeste
dName != "_blank") |
131 return requestedName; | 131 return requestedName; |
132 | 132 |
133 // Create a repeatable name for a child about to be added to us. The name mu
st be | 133 // Create a repeatable name for a child about to be added to us. The name mu
st be |
134 // unique within the frame tree. The string we generate includes a "path" of
names | 134 // unique within the frame tree. The string we generate includes a "path" of
names |
135 // from the root frame down to us. For this path to be unique, each set of s
iblings must | 135 // from the root frame down to us. For this path to be unique, each set of s
iblings must |
136 // contribute a unique name to the path, which can't collide with any HTML-a
ssigned names. | 136 // contribute a unique name to the path, which can't collide with any HTML-a
ssigned names. |
137 // We generate this path component by index in the child list along with an
unlikely | 137 // We generate this path component by index in the child list along with an
unlikely |
138 // frame name that can't be set in HTML because it collides with comment syn
tax. | 138 // frame name that can't be set in HTML because it collides with comment syn
tax. |
139 | 139 |
140 const char framePathPrefix[] = "<!--framePath "; | 140 const char framePathPrefix[] = "<!--framePath "; |
141 const int framePathPrefixLength = 14; | 141 const int framePathPrefixLength = 14; |
142 const int framePathSuffixLength = 3; | 142 const int framePathSuffixLength = 3; |
143 | 143 |
144 // Find the nearest parent that has a frame with a path in it. | 144 // Find the nearest parent that has a frame with a path in it. |
145 Vector<LocalFrame*, 16> chain; | 145 Vector<Frame*, 16> chain; |
146 LocalFrame* frame; | 146 Frame* frame; |
147 for (frame = toLocalFrame(m_thisFrame); frame; frame = frame->tree().parent(
)) { | 147 for (frame = m_thisFrame; frame; frame = frame->tree().parent()) { |
148 if (frame->tree().uniqueName().startsWith(framePathPrefix)) | 148 if (frame->tree().uniqueName().startsWith(framePathPrefix)) |
149 break; | 149 break; |
150 chain.append(frame); | 150 chain.append(frame); |
151 } | 151 } |
152 StringBuilder name; | 152 StringBuilder name; |
153 name.append(framePathPrefix); | 153 name.append(framePathPrefix); |
154 if (frame) { | 154 if (frame) { |
155 name.append(frame->tree().uniqueName().string().substring(framePathPrefi
xLength, | 155 name.append(frame->tree().uniqueName().string().substring(framePathPrefi
xLength, |
156 frame->tree().uniqueName().length() - framePathPrefixLength - frameP
athSuffixLength)); | 156 frame->tree().uniqueName().length() - framePathPrefixLength - frameP
athSuffixLength)); |
157 } | 157 } |
158 for (int i = chain.size() - 1; i >= 0; --i) { | 158 for (int i = chain.size() - 1; i >= 0; --i) { |
159 frame = chain[i]; | 159 frame = chain[i]; |
160 name.append('/'); | 160 name.append('/'); |
161 name.append(frame->tree().uniqueName()); | 161 name.append(frame->tree().uniqueName()); |
162 } | 162 } |
163 | 163 |
164 name.appendLiteral("/<!--frame"); | 164 name.appendLiteral("/<!--frame"); |
165 name.appendNumber(childCount() - 1); | 165 name.appendNumber(childCount() - 1); |
166 name.appendLiteral("-->-->"); | 166 name.appendLiteral("-->-->"); |
167 | 167 |
168 return name.toAtomicString(); | 168 return name.toAtomicString(); |
169 } | 169 } |
170 | 170 |
171 LocalFrame* FrameTree::scopedChild(unsigned index) const | 171 Frame* FrameTree::scopedChild(unsigned index) const |
172 { | 172 { |
| 173 if (!m_thisFrame->isLocalFrame()) |
| 174 return 0; |
173 TreeScope* scope = toLocalFrame(m_thisFrame)->document(); | 175 TreeScope* scope = toLocalFrame(m_thisFrame)->document(); |
174 if (!scope) | 176 if (!scope) |
175 return 0; | 177 return 0; |
176 | 178 |
177 unsigned scopedIndex = 0; | 179 unsigned scopedIndex = 0; |
178 for (LocalFrame* result = firstChild(); result; result = result->tree().next
Sibling()) { | 180 for (Frame* result = firstChild(); result; result = result->tree().nextSibli
ng()) { |
179 if (result->inScope(scope)) { | 181 if (result->isLocalFrame() && toLocalFrame(result)->inScope(scope)) { |
180 if (scopedIndex == index) | 182 if (scopedIndex == index) |
181 return result; | 183 return result; |
182 scopedIndex++; | 184 scopedIndex++; |
183 } | 185 } |
184 } | 186 } |
185 | 187 |
186 return 0; | 188 return 0; |
187 } | 189 } |
188 | 190 |
189 LocalFrame* FrameTree::scopedChild(const AtomicString& name) const | 191 Frame* FrameTree::scopedChild(const AtomicString& name) const |
190 { | 192 { |
| 193 if (!m_thisFrame->isLocalFrame()) |
| 194 return 0; |
| 195 |
191 TreeScope* scope = toLocalFrame(m_thisFrame)->document(); | 196 TreeScope* scope = toLocalFrame(m_thisFrame)->document(); |
192 if (!scope) | 197 if (!scope) |
193 return 0; | 198 return 0; |
194 | 199 |
195 for (LocalFrame* child = firstChild(); child; child = child->tree().nextSibl
ing()) | 200 for (Frame* child = firstChild(); child; child = child->tree().nextSibling()
) |
196 if (child->tree().name() == name && child->inScope(scope)) | 201 if (child->tree().name() == name && child->isLocalFrame() && toLocalFram
e(child)->inScope(scope)) |
197 return child; | 202 return child; |
198 return 0; | 203 return 0; |
199 } | 204 } |
200 | 205 |
201 inline unsigned FrameTree::scopedChildCount(TreeScope* scope) const | 206 inline unsigned FrameTree::scopedChildCount(TreeScope* scope) const |
202 { | 207 { |
203 if (!scope) | 208 if (!scope) |
204 return 0; | 209 return 0; |
205 | 210 |
206 unsigned scopedCount = 0; | 211 unsigned scopedCount = 0; |
207 for (LocalFrame* result = firstChild(); result; result = result->tree().next
Sibling()) { | 212 for (Frame* result = firstChild(); result; result = result->tree().nextSibli
ng()) { |
208 if (result->inScope(scope)) | 213 if (result->isLocalFrame() && toLocalFrame(result)->inScope(scope)) |
209 scopedCount++; | 214 scopedCount++; |
210 } | 215 } |
211 | 216 |
212 return scopedCount; | 217 return scopedCount; |
213 } | 218 } |
214 | 219 |
215 unsigned FrameTree::scopedChildCount() const | 220 unsigned FrameTree::scopedChildCount() const |
216 { | 221 { |
217 if (m_scopedChildCount == invalidChildCount) | 222 if (m_scopedChildCount == invalidChildCount) |
218 m_scopedChildCount = scopedChildCount(toLocalFrame(m_thisFrame)->documen
t()); | 223 m_scopedChildCount = scopedChildCount(toLocalFrame(m_thisFrame)->documen
t()); |
219 return m_scopedChildCount; | 224 return m_scopedChildCount; |
220 } | 225 } |
221 | 226 |
222 void FrameTree::invalidateScopedChildCount() | 227 void FrameTree::invalidateScopedChildCount() |
223 { | 228 { |
224 m_scopedChildCount = invalidChildCount; | 229 m_scopedChildCount = invalidChildCount; |
225 } | 230 } |
226 | 231 |
227 unsigned FrameTree::childCount() const | 232 unsigned FrameTree::childCount() const |
228 { | 233 { |
229 unsigned count = 0; | 234 unsigned count = 0; |
230 for (LocalFrame* result = firstChild(); result; result = result->tree().next
Sibling()) | 235 for (Frame* result = firstChild(); result; result = result->tree().nextSibli
ng()) |
231 ++count; | 236 ++count; |
232 return count; | 237 return count; |
233 } | 238 } |
234 | 239 |
235 LocalFrame* FrameTree::child(const AtomicString& name) const | 240 Frame* FrameTree::child(const AtomicString& name) const |
236 { | 241 { |
237 for (LocalFrame* child = firstChild(); child; child = child->tree().nextSibl
ing()) | 242 for (Frame* child = firstChild(); child; child = child->tree().nextSibling()
) |
238 if (child->tree().name() == name) | 243 if (child->tree().name() == name) |
239 return child; | 244 return child; |
240 return 0; | 245 return 0; |
241 } | 246 } |
242 | 247 |
243 LocalFrame* FrameTree::find(const AtomicString& name) const | 248 Frame* FrameTree::find(const AtomicString& name) const |
244 { | 249 { |
245 if (name == "_self" || name == "_current" || name.isEmpty()) | 250 if (name == "_self" || name == "_current" || name.isEmpty()) |
246 return toLocalFrame(m_thisFrame); | 251 return m_thisFrame; |
247 | 252 |
248 if (name == "_top") | 253 if (name == "_top") |
249 return top(); | 254 return top(); |
250 | 255 |
251 if (name == "_parent") | 256 if (name == "_parent") |
252 return parent() ? parent() : toLocalFrame(m_thisFrame); | 257 return parent() ? parent() : m_thisFrame; |
253 | 258 |
254 // Since "_blank" should never be any frame's name, the following just amoun
ts to an optimization. | 259 // Since "_blank" should never be any frame's name, the following just amoun
ts to an optimization. |
255 if (name == "_blank") | 260 if (name == "_blank") |
256 return 0; | 261 return 0; |
257 | 262 |
258 // Search subtree starting with this frame first. | 263 // Search subtree starting with this frame first. |
259 for (LocalFrame* frame = toLocalFrame(m_thisFrame); frame; frame = frame->tr
ee().traverseNext(toLocalFrame(m_thisFrame))) | 264 for (Frame* frame = m_thisFrame; frame; frame = frame->tree().traverseNext(m
_thisFrame)) |
260 if (frame->tree().name() == name) | 265 if (frame->tree().name() == name) |
261 return frame; | 266 return frame; |
262 | 267 |
263 // Search the entire tree for this page next. | 268 // Search the entire tree for this page next. |
264 Page* page = m_thisFrame->page(); | 269 Page* page = m_thisFrame->page(); |
265 | 270 |
266 // The frame could have been detached from the page, so check it. | 271 // The frame could have been detached from the page, so check it. |
267 if (!page) | 272 if (!page) |
268 return 0; | 273 return 0; |
269 | 274 |
270 for (LocalFrame* frame = page->mainFrame(); frame; frame = frame->tree().tra
verseNext()) | 275 for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverse
Next()) |
271 if (frame->tree().name() == name) | 276 if (frame->tree().name() == name) |
272 return frame; | 277 return frame; |
273 | 278 |
274 // Search the entire tree of each of the other pages in this namespace. | 279 // Search the entire tree of each of the other pages in this namespace. |
275 // FIXME: Is random order OK? | 280 // FIXME: Is random order OK? |
276 const HashSet<Page*>& pages = Page::ordinaryPages(); | 281 const HashSet<Page*>& pages = Page::ordinaryPages(); |
277 HashSet<Page*>::const_iterator end = pages.end(); | 282 HashSet<Page*>::const_iterator end = pages.end(); |
278 for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) { | 283 for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) { |
279 Page* otherPage = *it; | 284 Page* otherPage = *it; |
280 if (otherPage != page) { | 285 if (otherPage != page) { |
281 for (LocalFrame* frame = otherPage->mainFrame(); frame; frame = fram
e->tree().traverseNext()) { | 286 for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tr
ee().traverseNext()) { |
282 if (frame->tree().name() == name) | 287 if (frame->tree().name() == name) |
283 return frame; | 288 return frame; |
284 } | 289 } |
285 } | 290 } |
286 } | 291 } |
287 | 292 |
288 return 0; | 293 return 0; |
289 } | 294 } |
290 | 295 |
291 bool FrameTree::isDescendantOf(const LocalFrame* ancestor) const | 296 bool FrameTree::isDescendantOf(const Frame* ancestor) const |
292 { | 297 { |
293 if (!ancestor) | 298 if (!ancestor) |
294 return false; | 299 return false; |
295 | 300 |
296 if (m_thisFrame->page() != ancestor->page()) | 301 if (m_thisFrame->page() != ancestor->page()) |
297 return false; | 302 return false; |
298 | 303 |
299 for (LocalFrame* frame = toLocalFrame(m_thisFrame); frame; frame = frame->tr
ee().parent()) | 304 for (Frame* frame = m_thisFrame; frame; frame = frame->tree().parent()) |
300 if (frame == ancestor) | 305 if (frame == ancestor) |
301 return true; | 306 return true; |
302 return false; | 307 return false; |
303 } | 308 } |
304 | 309 |
305 LocalFrame* FrameTree::traverseNext(const LocalFrame* stayWithin) const | 310 Frame* FrameTree::traverseNext(const Frame* stayWithin) const |
306 { | 311 { |
307 LocalFrame* child = firstChild(); | 312 Frame* child = firstChild(); |
308 if (child) { | 313 if (child) { |
309 ASSERT(!stayWithin || child->tree().isDescendantOf(stayWithin)); | 314 ASSERT(!stayWithin || child->tree().isDescendantOf(stayWithin)); |
310 return child; | 315 return child; |
311 } | 316 } |
312 | 317 |
313 if (m_thisFrame == stayWithin) | 318 if (m_thisFrame == stayWithin) |
314 return 0; | 319 return 0; |
315 | 320 |
316 LocalFrame* sibling = nextSibling(); | 321 Frame* sibling = nextSibling(); |
317 if (sibling) { | 322 if (sibling) { |
318 ASSERT(!stayWithin || sibling->tree().isDescendantOf(stayWithin)); | 323 ASSERT(!stayWithin || sibling->tree().isDescendantOf(stayWithin)); |
319 return sibling; | 324 return sibling; |
320 } | 325 } |
321 | 326 |
322 LocalFrame* frame = toLocalFrame(m_thisFrame); | 327 Frame* frame = m_thisFrame; |
323 while (!sibling && (!stayWithin || frame->tree().parent() != stayWithin)) { | 328 while (!sibling && (!stayWithin || frame->tree().parent() != stayWithin)) { |
324 frame = frame->tree().parent(); | 329 frame = frame->tree().parent(); |
325 if (!frame) | 330 if (!frame) |
326 return 0; | 331 return 0; |
327 sibling = frame->tree().nextSibling(); | 332 sibling = frame->tree().nextSibling(); |
328 } | 333 } |
329 | 334 |
330 if (frame) { | 335 if (frame) { |
331 ASSERT(!stayWithin || !sibling || sibling->tree().isDescendantOf(stayWit
hin)); | 336 ASSERT(!stayWithin || !sibling || sibling->tree().isDescendantOf(stayWit
hin)); |
332 return sibling; | 337 return sibling; |
333 } | 338 } |
334 | 339 |
335 return 0; | 340 return 0; |
336 } | 341 } |
337 | 342 |
338 LocalFrame* FrameTree::traverseNextWithWrap(bool wrap) const | 343 Frame* FrameTree::traverseNextWithWrap(bool wrap) const |
339 { | 344 { |
340 if (LocalFrame* result = traverseNext()) | 345 if (Frame* result = traverseNext()) |
341 return result; | 346 return result; |
342 | 347 |
343 if (wrap) | 348 if (wrap) |
344 return m_thisFrame->page()->mainFrame(); | 349 return m_thisFrame->page()->mainFrame(); |
345 | 350 |
346 return 0; | 351 return 0; |
347 } | 352 } |
348 | 353 |
349 LocalFrame* FrameTree::traversePreviousWithWrap(bool wrap) const | 354 Frame* FrameTree::traversePreviousWithWrap(bool wrap) const |
350 { | 355 { |
351 // FIXME: besides the wrap feature, this is just the traversePreviousNode al
gorithm | 356 // FIXME: besides the wrap feature, this is just the traversePreviousNode al
gorithm |
352 | 357 |
353 if (LocalFrame* prevSibling = previousSibling()) | 358 if (Frame* prevSibling = previousSibling()) |
354 return prevSibling->tree().deepLastChild(); | 359 return prevSibling->tree().deepLastChild(); |
355 if (LocalFrame* parentFrame = parent()) | 360 if (Frame* parentFrame = parent()) |
356 return parentFrame; | 361 return parentFrame; |
357 | 362 |
358 // no siblings, no parent, self==top | 363 // no siblings, no parent, self==top |
359 if (wrap) | 364 if (wrap) |
360 return deepLastChild(); | 365 return deepLastChild(); |
361 | 366 |
362 // top view is always the last one in this ordering, so prev is nil without
wrap | 367 // top view is always the last one in this ordering, so prev is nil without
wrap |
363 return 0; | 368 return 0; |
364 } | 369 } |
365 | 370 |
366 LocalFrame* FrameTree::deepLastChild() const | 371 Frame* FrameTree::deepLastChild() const |
367 { | 372 { |
368 LocalFrame* result = toLocalFrame(m_thisFrame); | 373 Frame* result = m_thisFrame; |
369 for (LocalFrame* last = lastChild(); last; last = last->tree().lastChild()) | 374 for (Frame* last = lastChild(); last; last = last->tree().lastChild()) |
370 result = last; | 375 result = last; |
371 | 376 |
372 return result; | 377 return result; |
373 } | 378 } |
374 | 379 |
375 } // namespace WebCore | 380 } // namespace WebCore |
376 | 381 |
377 #ifndef NDEBUG | 382 #ifndef NDEBUG |
378 | 383 |
379 static void printIndent(int indent) | 384 static void printIndent(int indent) |
380 { | 385 { |
381 for (int i = 0; i < indent; ++i) | 386 for (int i = 0; i < indent; ++i) |
382 printf(" "); | 387 printf(" "); |
383 } | 388 } |
384 | 389 |
385 static void printFrames(const WebCore::LocalFrame* frame, const WebCore::LocalFr
ame* targetFrame, int indent) | 390 static void printFrames(const WebCore::Frame* frame, const WebCore::Frame* targe
tFrame, int indent) |
386 { | 391 { |
387 if (frame == targetFrame) { | 392 if (frame == targetFrame) { |
388 printf("--> "); | 393 printf("--> "); |
389 printIndent(indent - 1); | 394 printIndent(indent - 1); |
390 } else | 395 } else |
391 printIndent(indent); | 396 printIndent(indent); |
392 | 397 |
393 WebCore::FrameView* view = frame->view(); | 398 WebCore::FrameView* view = frame->isLocalFrame() ? toLocalFrame(frame)->view
() : 0; |
394 printf("LocalFrame %p %dx%d\n", frame, view ? view->width() : 0, view ? view
->height() : 0); | 399 printf("Frame %p %dx%d\n", frame, view ? view->width() : 0, view ? view->hei
ght() : 0); |
395 printIndent(indent); | 400 printIndent(indent); |
396 printf(" owner=%p\n", frame->owner()); | 401 printf(" owner=%p\n", frame->owner()); |
397 printIndent(indent); | 402 printIndent(indent); |
398 printf(" frameView=%p\n", view); | 403 printf(" frameView=%p\n", view); |
399 printIndent(indent); | 404 printIndent(indent); |
400 printf(" document=%p\n", frame->document()); | 405 printf(" document=%p\n", frame->isLocalFrame() ? toLocalFrame(frame)->docum
ent() : 0); |
401 printIndent(indent); | 406 printIndent(indent); |
402 printf(" uri=%s\n\n", frame->document()->url().string().utf8().data()); | 407 printf(" uri=%s\n\n", frame->isLocalFrame() ? toLocalFrame(frame)->document
()->url().string().utf8().data() : 0); |
403 | 408 |
404 for (WebCore::LocalFrame* child = frame->tree().firstChild(); child; child =
child->tree().nextSibling()) | 409 for (WebCore::Frame* child = frame->tree().firstChild(); child; child = chil
d->tree().nextSibling()) |
405 printFrames(child, targetFrame, indent + 1); | 410 printFrames(child, targetFrame, indent + 1); |
406 } | 411 } |
407 | 412 |
408 void showFrameTree(const WebCore::LocalFrame* frame) | 413 void showFrameTree(const WebCore::Frame* frame) |
409 { | 414 { |
410 if (!frame) { | 415 if (!frame) { |
411 printf("Null input frame\n"); | 416 printf("Null input frame\n"); |
412 return; | 417 return; |
413 } | 418 } |
414 | 419 |
415 printFrames(frame->tree().top(), frame, 0); | 420 printFrames(frame->tree().top(), frame, 0); |
416 } | 421 } |
417 | 422 |
418 #endif | 423 #endif |
OLD | NEW |