Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: Source/core/page/FrameTree.cpp

Issue 33353003: Have Frame::tree() return a reference (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase on master Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/page/FocusController.cpp ('k') | Source/core/page/Page.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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,
(...skipping 18 matching lines...) Expand all
29 #include "wtf/Vector.h" 29 #include "wtf/Vector.h"
30 #include "wtf/text/CString.h" 30 #include "wtf/text/CString.h"
31 #include "wtf/text/StringBuilder.h" 31 #include "wtf/text/StringBuilder.h"
32 32
33 using std::swap; 33 using std::swap;
34 34
35 namespace WebCore { 35 namespace WebCore {
36 36
37 FrameTree::~FrameTree() 37 FrameTree::~FrameTree()
38 { 38 {
39 for (Frame* child = firstChild(); child; child = child->tree()->nextSibling( )) 39 for (Frame* child = firstChild(); child; child = child->tree().nextSibling() )
40 child->setView(0); 40 child->setView(0);
41 } 41 }
42 42
43 void FrameTree::setName(const AtomicString& name) 43 void FrameTree::setName(const AtomicString& name)
44 { 44 {
45 m_name = name; 45 m_name = name;
46 if (!parent()) { 46 if (!parent()) {
47 m_uniqueName = name; 47 m_uniqueName = name;
48 return; 48 return;
49 } 49 }
50 m_uniqueName = AtomicString(); // Remove our old frame name so it's not cons idered in uniqueChildName. 50 m_uniqueName = AtomicString(); // Remove our old frame name so it's not cons idered in uniqueChildName.
51 m_uniqueName = parent()->tree()->uniqueChildName(name); 51 m_uniqueName = parent()->tree().uniqueChildName(name);
52 } 52 }
53 53
54 Frame* FrameTree::parent() const 54 Frame* FrameTree::parent() const
55 { 55 {
56 return m_parent; 56 return m_parent;
57 } 57 }
58 58
59 void FrameTree::appendChild(PassRefPtr<Frame> child) 59 void FrameTree::appendChild(PassRefPtr<Frame> child)
60 { 60 {
61 ASSERT(child->page() == m_thisFrame->page()); 61 ASSERT(child->page() == m_thisFrame->page());
62 child->tree()->m_parent = m_thisFrame; 62 child->tree().m_parent = m_thisFrame;
63 Frame* oldLast = m_lastChild; 63 Frame* oldLast = m_lastChild;
64 m_lastChild = child.get(); 64 m_lastChild = child.get();
65 65
66 if (oldLast) { 66 if (oldLast) {
67 child->tree()->m_previousSibling = oldLast; 67 child->tree().m_previousSibling = oldLast;
68 oldLast->tree()->m_nextSibling = child; 68 oldLast->tree().m_nextSibling = child;
69 } else 69 } else
70 m_firstChild = child; 70 m_firstChild = child;
71 71
72 m_scopedChildCount = invalidCount; 72 m_scopedChildCount = invalidCount;
73 73
74 ASSERT(!m_lastChild->tree()->m_nextSibling); 74 ASSERT(!m_lastChild->tree().m_nextSibling);
75 } 75 }
76 76
77 void FrameTree::removeChild(Frame* child) 77 void FrameTree::removeChild(Frame* child)
78 { 78 {
79 child->tree()->m_parent = 0; 79 child->tree().m_parent = 0;
80 80
81 // Slightly tricky way to prevent deleting the child until we are done with it, w/o 81 // Slightly tricky way to prevent deleting the child until we are done with it, w/o
82 // extra refs. These swaps leave the child in a circular list by itself. Cle aring its 82 // extra refs. These swaps leave the child in a circular list by itself. Cle aring its
83 // previous and next will then finally deref it. 83 // previous and next will then finally deref it.
84 84
85 RefPtr<Frame>& newLocationForNext = m_firstChild == child ? m_firstChild : c hild->tree()->m_previousSibling->tree()->m_nextSibling; 85 RefPtr<Frame>& newLocationForNext = m_firstChild == child ? m_firstChild : c hild->tree().m_previousSibling->tree().m_nextSibling;
86 Frame*& newLocationForPrevious = m_lastChild == child ? m_lastChild : child- >tree()->m_nextSibling->tree()->m_previousSibling; 86 Frame*& newLocationForPrevious = m_lastChild == child ? m_lastChild : child- >tree().m_nextSibling->tree().m_previousSibling;
87 swap(newLocationForNext, child->tree()->m_nextSibling); 87 swap(newLocationForNext, child->tree().m_nextSibling);
88 // For some inexplicable reason, the following line does not compile without the explicit std:: namespace 88 // For some inexplicable reason, the following line does not compile without the explicit std:: namespace
89 std::swap(newLocationForPrevious, child->tree()->m_previousSibling); 89 std::swap(newLocationForPrevious, child->tree().m_previousSibling);
90 90
91 child->tree()->m_previousSibling = 0; 91 child->tree().m_previousSibling = 0;
92 child->tree()->m_nextSibling = 0; 92 child->tree().m_nextSibling = 0;
93 93
94 m_scopedChildCount = invalidCount; 94 m_scopedChildCount = invalidCount;
95 } 95 }
96 96
97 AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const 97 AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
98 { 98 {
99 if (!requestedName.isEmpty() && !child(requestedName) && requestedName != "_ blank") 99 if (!requestedName.isEmpty() && !child(requestedName) && requestedName != "_ blank")
100 return requestedName; 100 return requestedName;
101 101
102 // Create a repeatable name for a child about to be added to us. The name mu st be 102 // Create a repeatable name for a child about to be added to us. The name mu st be
103 // unique within the frame tree. The string we generate includes a "path" of names 103 // unique within the frame tree. The string we generate includes a "path" of names
104 // from the root frame down to us. For this path to be unique, each set of s iblings must 104 // from the root frame down to us. For this path to be unique, each set of s iblings must
105 // contribute a unique name to the path, which can't collide with any HTML-a ssigned names. 105 // contribute a unique name to the path, which can't collide with any HTML-a ssigned names.
106 // We generate this path component by index in the child list along with an unlikely 106 // We generate this path component by index in the child list along with an unlikely
107 // frame name that can't be set in HTML because it collides with comment syn tax. 107 // frame name that can't be set in HTML because it collides with comment syn tax.
108 108
109 const char framePathPrefix[] = "<!--framePath "; 109 const char framePathPrefix[] = "<!--framePath ";
110 const int framePathPrefixLength = 14; 110 const int framePathPrefixLength = 14;
111 const int framePathSuffixLength = 3; 111 const int framePathSuffixLength = 3;
112 112
113 // Find the nearest parent that has a frame with a path in it. 113 // Find the nearest parent that has a frame with a path in it.
114 Vector<Frame*, 16> chain; 114 Vector<Frame*, 16> chain;
115 Frame* frame; 115 Frame* frame;
116 for (frame = m_thisFrame; frame; frame = frame->tree()->parent()) { 116 for (frame = m_thisFrame; frame; frame = frame->tree().parent()) {
117 if (frame->tree()->uniqueName().startsWith(framePathPrefix)) 117 if (frame->tree().uniqueName().startsWith(framePathPrefix))
118 break; 118 break;
119 chain.append(frame); 119 chain.append(frame);
120 } 120 }
121 StringBuilder name; 121 StringBuilder name;
122 name.append(framePathPrefix); 122 name.append(framePathPrefix);
123 if (frame) { 123 if (frame) {
124 name.append(frame->tree()->uniqueName().string().substring(framePathPref ixLength, 124 name.append(frame->tree().uniqueName().string().substring(framePathPrefi xLength,
125 frame->tree()->uniqueName().length() - framePathPrefixLength - frame PathSuffixLength)); 125 frame->tree().uniqueName().length() - framePathPrefixLength - frameP athSuffixLength));
126 } 126 }
127 for (int i = chain.size() - 1; i >= 0; --i) { 127 for (int i = chain.size() - 1; i >= 0; --i) {
128 frame = chain[i]; 128 frame = chain[i];
129 name.append('/'); 129 name.append('/');
130 name.append(frame->tree()->uniqueName()); 130 name.append(frame->tree().uniqueName());
131 } 131 }
132 132
133 name.appendLiteral("/<!--frame"); 133 name.appendLiteral("/<!--frame");
134 name.appendNumber(childCount()); 134 name.appendNumber(childCount());
135 name.appendLiteral("-->-->"); 135 name.appendLiteral("-->-->");
136 136
137 return name.toAtomicString(); 137 return name.toAtomicString();
138 } 138 }
139 139
140 Frame* FrameTree::scopedChild(unsigned index) const 140 Frame* FrameTree::scopedChild(unsigned index) const
141 { 141 {
142 TreeScope* scope = m_thisFrame->document(); 142 TreeScope* scope = m_thisFrame->document();
143 if (!scope) 143 if (!scope)
144 return 0; 144 return 0;
145 145
146 unsigned scopedIndex = 0; 146 unsigned scopedIndex = 0;
147 for (Frame* result = firstChild(); result; result = result->tree()->nextSibl ing()) { 147 for (Frame* result = firstChild(); result; result = result->tree().nextSibli ng()) {
148 if (result->inScope(scope)) { 148 if (result->inScope(scope)) {
149 if (scopedIndex == index) 149 if (scopedIndex == index)
150 return result; 150 return result;
151 scopedIndex++; 151 scopedIndex++;
152 } 152 }
153 } 153 }
154 154
155 return 0; 155 return 0;
156 } 156 }
157 157
158 Frame* FrameTree::scopedChild(const AtomicString& name) const 158 Frame* FrameTree::scopedChild(const AtomicString& name) const
159 { 159 {
160 TreeScope* scope = m_thisFrame->document(); 160 TreeScope* scope = m_thisFrame->document();
161 if (!scope) 161 if (!scope)
162 return 0; 162 return 0;
163 163
164 for (Frame* child = firstChild(); child; child = child->tree()->nextSibling( )) 164 for (Frame* child = firstChild(); child; child = child->tree().nextSibling() )
165 if (child->tree()->uniqueName() == name && child->inScope(scope)) 165 if (child->tree().uniqueName() == name && child->inScope(scope))
166 return child; 166 return child;
167 return 0; 167 return 0;
168 } 168 }
169 169
170 inline unsigned FrameTree::scopedChildCount(TreeScope* scope) const 170 inline unsigned FrameTree::scopedChildCount(TreeScope* scope) const
171 { 171 {
172 if (!scope) 172 if (!scope)
173 return 0; 173 return 0;
174 174
175 unsigned scopedCount = 0; 175 unsigned scopedCount = 0;
176 for (Frame* result = firstChild(); result; result = result->tree()->nextSibl ing()) { 176 for (Frame* result = firstChild(); result; result = result->tree().nextSibli ng()) {
177 if (result->inScope(scope)) 177 if (result->inScope(scope))
178 scopedCount++; 178 scopedCount++;
179 } 179 }
180 180
181 return scopedCount; 181 return scopedCount;
182 } 182 }
183 183
184 unsigned FrameTree::scopedChildCount() const 184 unsigned FrameTree::scopedChildCount() const
185 { 185 {
186 if (m_scopedChildCount == invalidCount) 186 if (m_scopedChildCount == invalidCount)
187 m_scopedChildCount = scopedChildCount(m_thisFrame->document()); 187 m_scopedChildCount = scopedChildCount(m_thisFrame->document());
188 return m_scopedChildCount; 188 return m_scopedChildCount;
189 } 189 }
190 190
191 unsigned FrameTree::childCount() const 191 unsigned FrameTree::childCount() const
192 { 192 {
193 unsigned count = 0; 193 unsigned count = 0;
194 for (Frame* result = firstChild(); result; result = result->tree()->nextSibl ing()) 194 for (Frame* result = firstChild(); result; result = result->tree().nextSibli ng())
195 ++count; 195 ++count;
196 return count; 196 return count;
197 } 197 }
198 198
199 Frame* FrameTree::child(const AtomicString& name) const 199 Frame* FrameTree::child(const AtomicString& name) const
200 { 200 {
201 for (Frame* child = firstChild(); child; child = child->tree()->nextSibling( )) 201 for (Frame* child = firstChild(); child; child = child->tree().nextSibling() )
202 if (child->tree()->uniqueName() == name) 202 if (child->tree().uniqueName() == name)
203 return child; 203 return child;
204 return 0; 204 return 0;
205 } 205 }
206 206
207 Frame* FrameTree::find(const AtomicString& name) const 207 Frame* FrameTree::find(const AtomicString& name) const
208 { 208 {
209 if (name == "_self" || name == "_current" || name.isEmpty()) 209 if (name == "_self" || name == "_current" || name.isEmpty())
210 return m_thisFrame; 210 return m_thisFrame;
211 211
212 if (name == "_top") 212 if (name == "_top")
213 return top(); 213 return top();
214 214
215 if (name == "_parent") 215 if (name == "_parent")
216 return parent() ? parent() : m_thisFrame; 216 return parent() ? parent() : m_thisFrame;
217 217
218 // Since "_blank" should never be any frame's name, the following just amoun ts to an optimization. 218 // Since "_blank" should never be any frame's name, the following just amoun ts to an optimization.
219 if (name == "_blank") 219 if (name == "_blank")
220 return 0; 220 return 0;
221 221
222 // Search subtree starting with this frame first. 222 // Search subtree starting with this frame first.
223 for (Frame* frame = m_thisFrame; frame; frame = frame->tree()->traverseNext( m_thisFrame)) 223 for (Frame* frame = m_thisFrame; frame; frame = frame->tree().traverseNext(m _thisFrame))
224 if (frame->tree()->uniqueName() == name) 224 if (frame->tree().uniqueName() == name)
225 return frame; 225 return frame;
226 226
227 // Search the entire tree for this page next. 227 // Search the entire tree for this page next.
228 Page* page = m_thisFrame->page(); 228 Page* page = m_thisFrame->page();
229 229
230 // The frame could have been detached from the page, so check it. 230 // The frame could have been detached from the page, so check it.
231 if (!page) 231 if (!page)
232 return 0; 232 return 0;
233 233
234 for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->travers eNext()) 234 for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverse Next())
235 if (frame->tree()->uniqueName() == name) 235 if (frame->tree().uniqueName() == name)
236 return frame; 236 return frame;
237 237
238 // Search the entire tree of each of the other pages in this namespace. 238 // Search the entire tree of each of the other pages in this namespace.
239 // FIXME: Is random order OK? 239 // FIXME: Is random order OK?
240 const HashSet<Page*>& pages = page->group().pages(); 240 const HashSet<Page*>& pages = page->group().pages();
241 HashSet<Page*>::const_iterator end = pages.end(); 241 HashSet<Page*>::const_iterator end = pages.end();
242 for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) { 242 for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
243 Page* otherPage = *it; 243 Page* otherPage = *it;
244 if (otherPage != page) { 244 if (otherPage != page) {
245 for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tr ee()->traverseNext()) { 245 for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tr ee().traverseNext()) {
246 if (frame->tree()->uniqueName() == name) 246 if (frame->tree().uniqueName() == name)
247 return frame; 247 return frame;
248 } 248 }
249 } 249 }
250 } 250 }
251 251
252 return 0; 252 return 0;
253 } 253 }
254 254
255 bool FrameTree::isDescendantOf(const Frame* ancestor) const 255 bool FrameTree::isDescendantOf(const Frame* ancestor) const
256 { 256 {
257 if (!ancestor) 257 if (!ancestor)
258 return false; 258 return false;
259 259
260 if (m_thisFrame->page() != ancestor->page()) 260 if (m_thisFrame->page() != ancestor->page())
261 return false; 261 return false;
262 262
263 for (Frame* frame = m_thisFrame; frame; frame = frame->tree()->parent()) 263 for (Frame* frame = m_thisFrame; frame; frame = frame->tree().parent())
264 if (frame == ancestor) 264 if (frame == ancestor)
265 return true; 265 return true;
266 return false; 266 return false;
267 } 267 }
268 268
269 Frame* FrameTree::traverseNext(const Frame* stayWithin) const 269 Frame* FrameTree::traverseNext(const Frame* stayWithin) const
270 { 270 {
271 Frame* child = firstChild(); 271 Frame* child = firstChild();
272 if (child) { 272 if (child) {
273 ASSERT(!stayWithin || child->tree()->isDescendantOf(stayWithin)); 273 ASSERT(!stayWithin || child->tree().isDescendantOf(stayWithin));
274 return child; 274 return child;
275 } 275 }
276 276
277 if (m_thisFrame == stayWithin) 277 if (m_thisFrame == stayWithin)
278 return 0; 278 return 0;
279 279
280 Frame* sibling = nextSibling(); 280 Frame* sibling = nextSibling();
281 if (sibling) { 281 if (sibling) {
282 ASSERT(!stayWithin || sibling->tree()->isDescendantOf(stayWithin)); 282 ASSERT(!stayWithin || sibling->tree().isDescendantOf(stayWithin));
283 return sibling; 283 return sibling;
284 } 284 }
285 285
286 Frame* frame = m_thisFrame; 286 Frame* frame = m_thisFrame;
287 while (!sibling && (!stayWithin || frame->tree()->parent() != stayWithin)) { 287 while (!sibling && (!stayWithin || frame->tree().parent() != stayWithin)) {
288 frame = frame->tree()->parent(); 288 frame = frame->tree().parent();
289 if (!frame) 289 if (!frame)
290 return 0; 290 return 0;
291 sibling = frame->tree()->nextSibling(); 291 sibling = frame->tree().nextSibling();
292 } 292 }
293 293
294 if (frame) { 294 if (frame) {
295 ASSERT(!stayWithin || !sibling || sibling->tree()->isDescendantOf(stayWi thin)); 295 ASSERT(!stayWithin || !sibling || sibling->tree().isDescendantOf(stayWit hin));
296 return sibling; 296 return sibling;
297 } 297 }
298 298
299 return 0; 299 return 0;
300 } 300 }
301 301
302 Frame* FrameTree::traverseNextWithWrap(bool wrap) const 302 Frame* FrameTree::traverseNextWithWrap(bool wrap) const
303 { 303 {
304 if (Frame* result = traverseNext()) 304 if (Frame* result = traverseNext())
305 return result; 305 return result;
306 306
307 if (wrap) 307 if (wrap)
308 return m_thisFrame->page()->mainFrame(); 308 return m_thisFrame->page()->mainFrame();
309 309
310 return 0; 310 return 0;
311 } 311 }
312 312
313 Frame* FrameTree::traversePreviousWithWrap(bool wrap) const 313 Frame* FrameTree::traversePreviousWithWrap(bool wrap) const
314 { 314 {
315 // FIXME: besides the wrap feature, this is just the traversePreviousNode al gorithm 315 // FIXME: besides the wrap feature, this is just the traversePreviousNode al gorithm
316 316
317 if (Frame* prevSibling = previousSibling()) 317 if (Frame* prevSibling = previousSibling())
318 return prevSibling->tree()->deepLastChild(); 318 return prevSibling->tree().deepLastChild();
319 if (Frame* parentFrame = parent()) 319 if (Frame* parentFrame = parent())
320 return parentFrame; 320 return parentFrame;
321 321
322 // no siblings, no parent, self==top 322 // no siblings, no parent, self==top
323 if (wrap) 323 if (wrap)
324 return deepLastChild(); 324 return deepLastChild();
325 325
326 // top view is always the last one in this ordering, so prev is nil without wrap 326 // top view is always the last one in this ordering, so prev is nil without wrap
327 return 0; 327 return 0;
328 } 328 }
329 329
330 Frame* FrameTree::deepLastChild() const 330 Frame* FrameTree::deepLastChild() const
331 { 331 {
332 Frame* result = m_thisFrame; 332 Frame* result = m_thisFrame;
333 for (Frame* last = lastChild(); last; last = last->tree()->lastChild()) 333 for (Frame* last = lastChild(); last; last = last->tree().lastChild())
334 result = last; 334 result = last;
335 335
336 return result; 336 return result;
337 } 337 }
338 338
339 Frame* FrameTree::top() const 339 Frame* FrameTree::top() const
340 { 340 {
341 Frame* frame = m_thisFrame; 341 Frame* frame = m_thisFrame;
342 for (Frame* parent = m_thisFrame; parent; parent = parent->tree()->parent()) 342 for (Frame* parent = m_thisFrame; parent; parent = parent->tree().parent())
343 frame = parent; 343 frame = parent;
344 return frame; 344 return frame;
345 } 345 }
346 346
347 } // namespace WebCore 347 } // namespace WebCore
348 348
349 #ifndef NDEBUG 349 #ifndef NDEBUG
350 350
351 static void printIndent(int indent) 351 static void printIndent(int indent)
352 { 352 {
(...skipping 13 matching lines...) Expand all
366 printf("Frame %p %dx%d\n", frame, view ? view->width() : 0, view ? view->hei ght() : 0); 366 printf("Frame %p %dx%d\n", frame, view ? view->width() : 0, view ? view->hei ght() : 0);
367 printIndent(indent); 367 printIndent(indent);
368 printf(" ownerElement=%p\n", frame->ownerElement()); 368 printf(" ownerElement=%p\n", frame->ownerElement());
369 printIndent(indent); 369 printIndent(indent);
370 printf(" frameView=%p\n", view); 370 printf(" frameView=%p\n", view);
371 printIndent(indent); 371 printIndent(indent);
372 printf(" document=%p\n", frame->document()); 372 printf(" document=%p\n", frame->document());
373 printIndent(indent); 373 printIndent(indent);
374 printf(" uri=%s\n\n", frame->document()->documentURI().utf8().data()); 374 printf(" uri=%s\n\n", frame->document()->documentURI().utf8().data());
375 375
376 for (WebCore::Frame* child = frame->tree()->firstChild(); child; child = chi ld->tree()->nextSibling()) 376 for (WebCore::Frame* child = frame->tree().firstChild(); child; child = chil d->tree().nextSibling())
377 printFrames(child, targetFrame, indent + 1); 377 printFrames(child, targetFrame, indent + 1);
378 } 378 }
379 379
380 void showFrameTree(const WebCore::Frame* frame) 380 void showFrameTree(const WebCore::Frame* frame)
381 { 381 {
382 if (!frame) { 382 if (!frame) {
383 printf("Null input frame\n"); 383 printf("Null input frame\n");
384 return; 384 return;
385 } 385 }
386 386
387 printFrames(frame->tree()->top(), frame, 0); 387 printFrames(frame->tree().top(), frame, 0);
388 } 388 }
389 389
390 #endif 390 #endif
OLDNEW
« no previous file with comments | « Source/core/page/FocusController.cpp ('k') | Source/core/page/Page.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698