OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. |
3 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 3 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 | 240 |
241 RenderCounter::rendererSubtreeAttached(child); | 241 RenderCounter::rendererSubtreeAttached(child); |
242 child->setNeedsLayoutAndPrefWidthsRecalc(); | 242 child->setNeedsLayoutAndPrefWidthsRecalc(); |
243 if (!owner->normalChildNeedsLayout()) | 243 if (!owner->normalChildNeedsLayout()) |
244 owner->setChildNeedsLayout(true); // We may supply the static position f
or an absolute positioned child. | 244 owner->setChildNeedsLayout(true); // We may supply the static position f
or an absolute positioned child. |
245 | 245 |
246 if (AXObjectCache::accessibilityEnabled()) | 246 if (AXObjectCache::accessibilityEnabled()) |
247 owner->document()->axObjectCache()->childrenChanged(owner); | 247 owner->document()->axObjectCache()->childrenChanged(owner); |
248 } | 248 } |
249 | 249 |
250 static RenderObject* beforeAfterContainer(RenderObject* container, PseudoId type
) | |
251 { | |
252 if (type == BEFORE) { | |
253 // An anonymous (generated) inline run-in that has PseudoId BEFORE must
come from a grandparent. | |
254 // Therefore we should skip these generated run-ins when checking our im
mediate children. | |
255 // If we don't find our :before child immediately, then we should check
if we own a | |
256 // generated inline run-in in the next level of children. | |
257 RenderObject* first = container; | |
258 do { | |
259 // Skip list markers and generated run-ins | |
260 first = first->firstChild(); | |
261 while (first && (first->isListMarker() || (first->isRenderInline() &
& first->isRunIn() && first->isAnonymous()))) | |
262 first = first->nextSibling(); | |
263 } while (first && first->isAnonymous() && first->style()->styleType() ==
NOPSEUDO); | |
264 | |
265 if (!first) | |
266 return 0; | |
267 | |
268 if (first->style()->styleType() == type) | |
269 return first; | |
270 | |
271 // Check for a possible generated run-in, using run-in positioning rules
. | |
272 // Skip inlines and floating / positioned blocks, and place as the first
child. | |
273 first = container->firstChild(); | |
274 if (!first->isRenderBlock()) | |
275 return 0; | |
276 while (first && first->isFloatingOrPositioned()) | |
277 first = first->nextSibling(); | |
278 if (first) { | |
279 first = first->firstChild(); | |
280 // We still need to skip any list markers that could exist before th
e run-in. | |
281 while (first && first->isListMarker()) | |
282 first = first->nextSibling(); | |
283 if (first && first->style()->styleType() == type && first->isRenderI
nline() && first->isRunIn() && first->isAnonymous()) | |
284 return first; | |
285 } | |
286 return 0; | |
287 } | |
288 | |
289 if (type == AFTER) { | |
290 RenderObject* last = container; | |
291 do { | |
292 last = last->lastChild(); | |
293 } while (last && last->isAnonymous() && last->style()->styleType() == NO
PSEUDO && !last->isListMarker()); | |
294 if (last && last->style()->styleType() != type) | |
295 return 0; | |
296 return last; | |
297 } | |
298 | |
299 ASSERT_NOT_REACHED(); | |
300 return 0; | |
301 } | |
302 | |
303 static RenderObject* findBeforeAfterParent(RenderObject* object) | 250 static RenderObject* findBeforeAfterParent(RenderObject* object) |
304 { | 251 { |
305 // Only table parts need to search for the :before or :after parent | 252 // Only table parts need to search for the :before or :after parent |
306 if (!(object->isTable() || object->isTableSection() || object->isTableRow())
) | 253 if (!(object->isTable() || object->isTableSection() || object->isTableRow())
) |
307 return object; | 254 return object; |
308 | 255 |
309 RenderObject* beforeAfterParent = object; | 256 RenderObject* beforeAfterParent = object; |
310 while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterPare
nt->isImage())) | 257 while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterPare
nt->isImage())) |
311 beforeAfterParent = beforeAfterParent->firstChild(); | 258 beforeAfterParent = beforeAfterParent->firstChild(); |
312 return beforeAfterParent; | 259 return beforeAfterParent; |
(...skipping 10 matching lines...) Expand all Loading... |
323 if (container->isCounter()) { | 270 if (container->isCounter()) { |
324 toRenderCounter(container)->invalidate(identifier); | 271 toRenderCounter(container)->invalidate(identifier); |
325 return; | 272 return; |
326 } | 273 } |
327 for (RenderObject* content = container->firstChild(); content; content = con
tent->nextSibling()) { | 274 for (RenderObject* content = container->firstChild(); content; content = con
tent->nextSibling()) { |
328 if (content->isCounter()) | 275 if (content->isCounter()) |
329 toRenderCounter(content)->invalidate(identifier); | 276 toRenderCounter(content)->invalidate(identifier); |
330 } | 277 } |
331 } | 278 } |
332 | 279 |
333 void RenderObjectChildList::invalidateCounters(RenderObject* owner, const Atomic
String& identifier) | 280 void RenderObjectChildList::invalidateCounters(const RenderObject* owner, const
AtomicString& identifier) |
334 { | 281 { |
335 ASSERT(!owner->documentBeingDestroyed()); | 282 ASSERT(!owner->documentBeingDestroyed()); |
336 invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE), identifie
r); | 283 invalidateCountersInContainer(beforePseudoElementRenderer(owner), identifier
); |
337 invalidateCountersInContainer(beforeAfterContainer(owner, AFTER), identifier
); | 284 invalidateCountersInContainer(afterPseudoElementRenderer(owner), identifier)
; |
338 } | 285 } |
339 | 286 |
340 void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
Id type, RenderObject* styledObject) | 287 RenderObject* RenderObjectChildList::beforePseudoElementRenderer(const RenderObj
ect* owner) const |
| 288 { |
| 289 // An anonymous (generated) inline run-in that has PseudoId BEFORE must come
from a grandparent. |
| 290 // Therefore we should skip these generated run-ins when checking our immedi
ate children. |
| 291 // If we don't find our :before child immediately, then we should check if w
e own a |
| 292 // generated inline run-in in the next level of children. |
| 293 RenderObject* first = const_cast<RenderObject*>(owner); |
| 294 do { |
| 295 // Skip list markers and generated run-ins |
| 296 first = first->firstChild(); |
| 297 while (first && (first->isListMarker() || (first->isRenderInline() && fi
rst->isRunIn() && first->isAnonymous()))) |
| 298 first = first->nextSibling(); |
| 299 } while (first && first->isAnonymous() && first->style()->styleType() == NOP
SEUDO); |
| 300 |
| 301 if (!first) |
| 302 return 0; |
| 303 |
| 304 if (first->style()->styleType() == BEFORE) |
| 305 return first; |
| 306 |
| 307 // Check for a possible generated run-in, using run-in positioning rules. |
| 308 // Skip inlines and floating / positioned blocks, and place as the first chi
ld. |
| 309 first = owner->firstChild(); |
| 310 if (!first->isRenderBlock()) |
| 311 return 0; |
| 312 while (first && first->isFloatingOrPositioned()) |
| 313 first = first->nextSibling(); |
| 314 if (first) { |
| 315 first = first->firstChild(); |
| 316 // We still need to skip any list markers that could exist before the ru
n-in. |
| 317 while (first && first->isListMarker()) |
| 318 first = first->nextSibling(); |
| 319 if (first && first->style()->styleType() == BEFORE && first->isRenderInl
ine() && first->isRunIn() && first->isAnonymous()) |
| 320 return first; |
| 321 } |
| 322 return 0; |
| 323 } |
| 324 |
| 325 RenderObject* RenderObjectChildList::afterPseudoElementRenderer(const RenderObje
ct* owner) const |
| 326 { |
| 327 RenderObject* last = const_cast<RenderObject*>(owner); |
| 328 do { |
| 329 last = last->lastChild(); |
| 330 } while (last && last->isAnonymous() && last->style()->styleType() == NOPSEU
DO && !last->isListMarker()); |
| 331 if (last && last->style()->styleType() != AFTER) |
| 332 return 0; |
| 333 return last; |
| 334 } |
| 335 |
| 336 void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
Id type, const RenderObject* styledObject) |
341 { | 337 { |
342 // Double check that the document did in fact use generated content rules.
Otherwise we should not have been called. | 338 // Double check that the document did in fact use generated content rules.
Otherwise we should not have been called. |
343 ASSERT(owner->document()->usesBeforeAfterRules()); | 339 ASSERT(owner->document()->usesBeforeAfterRules()); |
344 | 340 |
345 // In CSS2, before/after pseudo-content cannot nest. Check this first. | 341 // In CSS2, before/after pseudo-content cannot nest. Check this first. |
346 if (owner->style()->styleType() == BEFORE || owner->style()->styleType() ==
AFTER) | 342 if (owner->style()->styleType() == BEFORE || owner->style()->styleType() ==
AFTER) |
347 return; | 343 return; |
348 | 344 |
349 if (!styledObject) | 345 if (!styledObject) |
350 styledObject = owner; | 346 styledObject = owner; |
351 | 347 |
352 RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type); | 348 RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type); |
353 RenderObject* child = beforeAfterContainer(owner, type); | 349 RenderObject* child; |
| 350 switch (type) { |
| 351 case BEFORE: |
| 352 child = beforePseudoElementRenderer(owner); |
| 353 break; |
| 354 case AFTER: |
| 355 child = afterPseudoElementRenderer(owner); |
| 356 break; |
| 357 default: |
| 358 ASSERT_NOT_REACHED(); |
| 359 return; |
| 360 } |
354 | 361 |
355 // Whether or not we currently have generated content attached. | 362 // Whether or not we currently have generated content attached. |
356 bool oldContentPresent = child; | 363 bool oldContentPresent = child; |
357 | 364 |
358 // Whether or not we now want generated content. | 365 // Whether or not we now want generated content. |
359 bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display()
!= NONE; | 366 bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display()
!= NONE; |
360 | 367 |
361 // For <q><p/></q>, if this object is the inline continuation of the <q>, we
only want to generate | 368 // For <q><p/></q>, if this object is the inline continuation of the <q>, we
only want to generate |
362 // :after content and not :before content. | 369 // :after content and not :before content. |
363 if (newContentWanted && type == BEFORE && owner->isElementContinuation()) | 370 if (newContentWanted && type == BEFORE && owner->isElementContinuation()) |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 renderer = new (owner->renderArena()) RenderCounter(owner->docum
ent(), *content->counter()); | 464 renderer = new (owner->renderArena()) RenderCounter(owner->docum
ent(), *content->counter()); |
458 renderer->setStyle(pseudoElementStyle); | 465 renderer->setStyle(pseudoElementStyle); |
459 break; | 466 break; |
460 } | 467 } |
461 | 468 |
462 if (renderer) { | 469 if (renderer) { |
463 if (!generatedContentContainer) { | 470 if (!generatedContentContainer) { |
464 // Make a generated box that might be any display type now that
we are able to drill down into children | 471 // Make a generated box that might be any display type now that
we are able to drill down into children |
465 // to find the original content properly. | 472 // to find the original content properly. |
466 generatedContentContainer = RenderObject::createObject(owner->do
cument(), pseudoElementStyle); | 473 generatedContentContainer = RenderObject::createObject(owner->do
cument(), pseudoElementStyle); |
| 474 ASSERT(styledObject->node()); // The styled object cannot be ano
nymous or else it could not have ':before' or ':after' pseudo elements. |
| 475 generatedContentContainer->setNode(styledObject->node()); // Thi
s allows access to the generatingNode. |
467 generatedContentContainer->setStyle(pseudoElementStyle); | 476 generatedContentContainer->setStyle(pseudoElementStyle); |
468 owner->addChild(generatedContentContainer, insertBefore); | 477 owner->addChild(generatedContentContainer, insertBefore); |
469 } | 478 } |
470 if (generatedContentContainer->isChildAllowed(renderer, pseudoElemen
tStyle)) | 479 if (generatedContentContainer->isChildAllowed(renderer, pseudoElemen
tStyle)) |
471 generatedContentContainer->addChild(renderer); | 480 generatedContentContainer->addChild(renderer); |
472 else | 481 else |
473 renderer->destroy(); | 482 renderer->destroy(); |
474 } | 483 } |
475 } | 484 } |
476 } | 485 } |
477 | 486 |
478 } // namespace WebCore | 487 } // namespace WebCore |
OLD | NEW |