OLD | NEW |
1 /** | 1 /** |
2 * Copyright (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) | 2 * Copyright (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) |
3 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. | 3 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. |
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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
identifier, bool isReset, CounterNode*& parent, CounterNode*& previousSibling) | 296 static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
identifier, bool isReset, CounterNode*& parent, CounterNode*& previousSibling) |
297 { | 297 { |
298 // We cannot stop searching for counters with the same identifier before we
also | 298 // We cannot stop searching for counters with the same identifier before we
also |
299 // check this renderer, because it may affect the positioning in the tree of
our counter. | 299 // check this renderer, because it may affect the positioning in the tree of
our counter. |
300 RenderObject* searchEndRenderer = previousSiblingOrParent(counterOwner); | 300 RenderObject* searchEndRenderer = previousSiblingOrParent(counterOwner); |
301 // We check renderers in preOrder from the renderer that our counter is atta
ched to | 301 // We check renderers in preOrder from the renderer that our counter is atta
ched to |
302 // towards the begining of the document for counters with the same identifie
r as the one | 302 // towards the begining of the document for counters with the same identifie
r as the one |
303 // we are trying to find a place for. This is the next renderer to be checke
d. | 303 // we are trying to find a place for. This is the next renderer to be checke
d. |
304 RenderObject* currentRenderer = previousInPreOrder(counterOwner); | 304 RenderObject* currentRenderer = previousInPreOrder(counterOwner); |
305 previousSibling = 0; | 305 previousSibling = 0; |
| 306 RefPtr<CounterNode> previousSiblingProtector = 0; |
| 307 |
306 while (currentRenderer) { | 308 while (currentRenderer) { |
307 CounterNode* currentCounter = makeCounterNode(currentRenderer, identifie
r, false); | 309 CounterNode* currentCounter = makeCounterNode(currentRenderer, identifie
r, false); |
308 if (searchEndRenderer == currentRenderer) { | 310 if (searchEndRenderer == currentRenderer) { |
309 // We may be at the end of our search. | 311 // We may be at the end of our search. |
310 if (currentCounter) { | 312 if (currentCounter) { |
311 // We have a suitable counter on the EndSearchRenderer. | 313 // We have a suitable counter on the EndSearchRenderer. |
312 if (previousSibling) { // But we already found another counter t
hat we come after. | 314 if (previousSiblingProtector) { // But we already found another
counter that we come after. |
313 if (currentCounter->actsAsReset()) { | 315 if (currentCounter->actsAsReset()) { |
314 // We found a reset counter that is on a renderer that i
s a sibling of ours or a parent. | 316 // We found a reset counter that is on a renderer that i
s a sibling of ours or a parent. |
315 if (isReset && areRenderersElementsSiblings(currentRende
rer, counterOwner)) { | 317 if (isReset && areRenderersElementsSiblings(currentRende
rer, counterOwner)) { |
316 // We are also a reset counter and the previous rese
t was on a sibling renderer | 318 // We are also a reset counter and the previous rese
t was on a sibling renderer |
317 // hence we are the next sibling of that counter if
that reset is not a root or | 319 // hence we are the next sibling of that counter if
that reset is not a root or |
318 // we are a root node if that reset is a root. | 320 // we are a root node if that reset is a root. |
319 parent = currentCounter->parent(); | 321 parent = currentCounter->parent(); |
320 previousSibling = parent ? currentCounter : 0; | 322 previousSibling = parent ? currentCounter : 0; |
321 return parent; | 323 return parent; |
322 } | 324 } |
323 // We are not a reset node or the previous reset must be
on an ancestor of our owner renderer | 325 // We are not a reset node or the previous reset must be
on an ancestor of our owner renderer |
324 // hence we must be a child of that reset counter. | 326 // hence we must be a child of that reset counter. |
325 parent = currentCounter; | 327 parent = currentCounter; |
326 // In some cases renders can be reparented (ex. nodes in
side a table but not in a column or row). | 328 // In some cases renders can be reparented (ex. nodes in
side a table but not in a column or row). |
327 // In these cases the identified previousSibling will be
invalid as its parent is different from | 329 // In these cases the identified previousSibling will be
invalid as its parent is different from |
328 // our identified parent. | 330 // our identified parent. |
329 if (previousSibling->parent() != currentCounter) | 331 if (previousSiblingProtector->parent() != currentCounter
) |
330 previousSibling = 0; | 332 previousSiblingProtector = 0; |
| 333 |
| 334 previousSibling = previousSiblingProtector.get(); |
331 return true; | 335 return true; |
332 } | 336 } |
333 // CurrentCounter, the counter at the EndSearchRenderer, is
not reset. | 337 // CurrentCounter, the counter at the EndSearchRenderer, is
not reset. |
334 if (!isReset || !areRenderersElementsSiblings(currentRendere
r, counterOwner)) { | 338 if (!isReset || !areRenderersElementsSiblings(currentRendere
r, counterOwner)) { |
335 // If the node we are placing is not reset or we have fo
und a counter that is attached | 339 // If the node we are placing is not reset or we have fo
und a counter that is attached |
336 // to an ancestor of the placed counter's owner renderer
we know we are a sibling of that node. | 340 // to an ancestor of the placed counter's owner renderer
we know we are a sibling of that node. |
337 ASSERT(currentCounter->parent() == previousSibling->pare
nt()); | 341 ASSERT(currentCounter->parent() == previousSiblingProtec
tor->parent()); |
338 parent = currentCounter->parent(); | 342 parent = currentCounter->parent(); |
| 343 previousSibling = previousSiblingProtector.get(); |
339 return true; | 344 return true; |
340 } | 345 } |
341 } else { | 346 } else { |
342 // We are at the potential end of the search, but we had no
previous sibling candidate | 347 // We are at the potential end of the search, but we had no
previous sibling candidate |
343 // In this case we follow pretty much the same logic as abov
e but no ASSERTs about | 348 // In this case we follow pretty much the same logic as abov
e but no ASSERTs about |
344 // previousSibling, and when we are a sibling of the end cou
nter we must set previousSibling | 349 // previousSibling, and when we are a sibling of the end cou
nter we must set previousSibling |
345 // to currentCounter. | 350 // to currentCounter. |
346 if (currentCounter->actsAsReset()) { | 351 if (currentCounter->actsAsReset()) { |
347 if (isReset && areRenderersElementsSiblings(currentRende
rer, counterOwner)) { | 352 if (isReset && areRenderersElementsSiblings(currentRende
rer, counterOwner)) { |
348 parent = currentCounter->parent(); | 353 parent = currentCounter->parent(); |
349 previousSibling = currentCounter; | 354 previousSibling = currentCounter; |
350 return parent; | 355 return parent; |
351 } | 356 } |
352 parent = currentCounter; | 357 parent = currentCounter; |
| 358 previousSibling = previousSiblingProtector.get(); |
353 return true; | 359 return true; |
354 } | 360 } |
355 if (!isReset || !areRenderersElementsSiblings(currentRendere
r, counterOwner)) { | 361 if (!isReset || !areRenderersElementsSiblings(currentRendere
r, counterOwner)) { |
356 parent = currentCounter->parent(); | 362 parent = currentCounter->parent(); |
357 previousSibling = currentCounter; | 363 previousSibling = currentCounter; |
358 return true; | 364 return true; |
359 } | 365 } |
360 previousSibling = currentCounter; | 366 previousSiblingProtector = currentCounter; |
361 } | 367 } |
362 } | 368 } |
363 // We come here if the previous sibling or parent of our owner rende
rer had no | 369 // We come here if the previous sibling or parent of our owner rende
rer had no |
364 // good counter, or we are a reset node and the counter on the previ
ous sibling | 370 // good counter, or we are a reset node and the counter on the previ
ous sibling |
365 // of our owner renderer was not a reset counter. | 371 // of our owner renderer was not a reset counter. |
366 // Set a new goal for the end of the search. | 372 // Set a new goal for the end of the search. |
367 searchEndRenderer = previousSiblingOrParent(currentRenderer); | 373 searchEndRenderer = previousSiblingOrParent(currentRenderer); |
368 } else { | 374 } else { |
369 // We are searching descendants of a previous sibling of the rendere
r that the | 375 // We are searching descendants of a previous sibling of the rendere
r that the |
370 // counter being placed is attached to. | 376 // counter being placed is attached to. |
371 if (currentCounter) { | 377 if (currentCounter) { |
372 // We found a suitable counter. | 378 // We found a suitable counter. |
373 if (previousSibling) { | 379 if (previousSiblingProtector) { |
374 // Since we had a suitable previous counter before, we shoul
d only consider this one as our | 380 // Since we had a suitable previous counter before, we shoul
d only consider this one as our |
375 // previousSibling if it is a reset counter and hence the cu
rrent previousSibling is its child. | 381 // previousSibling if it is a reset counter and hence the cu
rrent previousSibling is its child. |
376 if (currentCounter->actsAsReset()) { | 382 if (currentCounter->actsAsReset()) { |
377 previousSibling = currentCounter; | 383 previousSiblingProtector = currentCounter; |
378 // We are no longer interested in previous siblings of t
he currentRenderer or their children | 384 // We are no longer interested in previous siblings of t
he currentRenderer or their children |
379 // as counters they may have attached cannot be the prev
ious sibling of the counter we are placing. | 385 // as counters they may have attached cannot be the prev
ious sibling of the counter we are placing. |
380 currentRenderer = parentElement(currentRenderer)->render
er(); | 386 currentRenderer = parentElement(currentRenderer)->render
er(); |
381 continue; | 387 continue; |
382 } | 388 } |
383 } else | 389 } else |
384 previousSibling = currentCounter; | 390 previousSiblingProtector = currentCounter; |
385 currentRenderer = previousSiblingOrParent(currentRenderer); | 391 currentRenderer = previousSiblingOrParent(currentRenderer); |
386 continue; | 392 continue; |
387 } | 393 } |
388 } | 394 } |
389 // This function is designed so that the same test is not done twice in
an iteration, except for this one | 395 // This function is designed so that the same test is not done twice in
an iteration, except for this one |
390 // which may be done twice in some cases. Rearranging the decision point
s though, to accommodate this | 396 // which may be done twice in some cases. Rearranging the decision point
s though, to accommodate this |
391 // performance improvement would create more code duplication than is wo
rthwhile in my oppinion and may further | 397 // performance improvement would create more code duplication than is wo
rthwhile in my oppinion and may further |
392 // impede the readability of this already complex algorithm. | 398 // impede the readability of this already complex algorithm. |
393 if (previousSibling) | 399 if (previousSiblingProtector) |
394 currentRenderer = previousSiblingOrParent(currentRenderer); | 400 currentRenderer = previousSiblingOrParent(currentRenderer); |
395 else | 401 else |
396 currentRenderer = previousInPreOrder(currentRenderer); | 402 currentRenderer = previousInPreOrder(currentRenderer); |
397 } | 403 } |
398 return false; | 404 return false; |
399 } | 405 } |
400 | 406 |
401 static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& id
entifier, bool alwaysCreateCounter) | 407 static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& id
entifier, bool alwaysCreateCounter) |
402 { | 408 { |
403 ASSERT(object); | 409 ASSERT(object); |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 fprintf(stderr, " "); | 711 fprintf(stderr, " "); |
706 fprintf(stderr, "%p N:%p P:%p PS:%p NS:%p C:%p\n", | 712 fprintf(stderr, "%p N:%p P:%p PS:%p NS:%p C:%p\n", |
707 current, current->node(), current->parent(), current->previousSiblin
g(), | 713 current, current->node(), current->parent(), current->previousSiblin
g(), |
708 current->nextSibling(), current->m_hasCounterNodeMap? | 714 current->nextSibling(), current->m_hasCounterNodeMap? |
709 counterName ? WebCore::counterMaps().get(current)->get(identifier.im
pl()).get() : (WebCore::CounterNode*)1 : (WebCore::CounterNode*)0); | 715 counterName ? WebCore::counterMaps().get(current)->get(identifier.im
pl()).get() : (WebCore::CounterNode*)1 : (WebCore::CounterNode*)0); |
710 } | 716 } |
711 fflush(stderr); | 717 fflush(stderr); |
712 } | 718 } |
713 | 719 |
714 #endif // NDEBUG | 720 #endif // NDEBUG |
OLD | NEW |