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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 return nullptr; | 66 return nullptr; |
67 } | 67 } |
68 | 68 |
69 // This function processes the layoutObject tree in the order of the DOM tree | 69 // This function processes the layoutObject tree in the order of the DOM tree |
70 // including pseudo elements as defined in CSS 2.1. This method will always | 70 // including pseudo elements as defined in CSS 2.1. This method will always |
71 // return either a previous object within the same contain: style scope or | 71 // return either a previous object within the same contain: style scope or |
72 // nullptr. | 72 // nullptr. |
73 static LayoutObject* previousInPreOrderRespectingContainment( | 73 static LayoutObject* previousInPreOrderRespectingContainment( |
74 const LayoutObject& object) { | 74 const LayoutObject& object) { |
75 Element* self = toElement(object.node()); | 75 Element* self = toElement(object.node()); |
76 ASSERT(self); | 76 DCHECK(self); |
77 Element* previous = ElementTraversal::previousIncludingPseudo(*self); | 77 Element* previous = ElementTraversal::previousIncludingPseudo(*self); |
78 Element* styleContainAncestor = ancestorStyleContainmentObject(*self); | 78 Element* styleContainAncestor = ancestorStyleContainmentObject(*self); |
79 | 79 |
80 while (1) { | 80 while (1) { |
81 while (previous && !previous->layoutObject()) | 81 while (previous && !previous->layoutObject()) |
82 previous = ElementTraversal::previousIncludingPseudo(*previous); | 82 previous = ElementTraversal::previousIncludingPseudo(*previous); |
83 if (!previous) | 83 if (!previous) |
84 return nullptr; | 84 return nullptr; |
85 Element* previousStyleContainAncestor = | 85 Element* previousStyleContainAncestor = |
86 ancestorStyleContainmentObject(*previous); | 86 ancestorStyleContainmentObject(*previous); |
87 if (previousStyleContainAncestor == styleContainAncestor) | 87 if (previousStyleContainAncestor == styleContainAncestor) |
88 return previous->layoutObject(); | 88 return previous->layoutObject(); |
89 if (!previousStyleContainAncestor) | 89 if (!previousStyleContainAncestor) |
90 return nullptr; | 90 return nullptr; |
91 previous = previousStyleContainAncestor; | 91 previous = previousStyleContainAncestor; |
92 } | 92 } |
93 } | 93 } |
94 | 94 |
95 // This function processes the layoutObject tree in the order of the DOM tree | 95 // This function processes the layoutObject tree in the order of the DOM tree |
96 // including pseudo elements as defined in CSS 2.1. This method avoids crossing | 96 // including pseudo elements as defined in CSS 2.1. This method avoids crossing |
97 // contain: style boundaries. | 97 // contain: style boundaries. |
98 static LayoutObject* previousSiblingOrParentRespectingContainment( | 98 static LayoutObject* previousSiblingOrParentRespectingContainment( |
99 const LayoutObject& object) { | 99 const LayoutObject& object) { |
100 Element* self = toElement(object.node()); | 100 Element* self = toElement(object.node()); |
101 ASSERT(self); | 101 DCHECK(self); |
102 Element* previous = ElementTraversal::pseudoAwarePreviousSibling(*self); | 102 Element* previous = ElementTraversal::pseudoAwarePreviousSibling(*self); |
103 while (previous && !previous->layoutObject()) | 103 while (previous && !previous->layoutObject()) |
104 previous = ElementTraversal::pseudoAwarePreviousSibling(*previous); | 104 previous = ElementTraversal::pseudoAwarePreviousSibling(*previous); |
105 if (previous) | 105 if (previous) |
106 return previous->layoutObject(); | 106 return previous->layoutObject(); |
107 previous = self->parentElement(); | 107 previous = self->parentElement(); |
108 return previous && previous->layoutObject() && | 108 return previous && previous->layoutObject() && |
109 !(previous->layoutObject()->style()->contain() & ContainsStyle) | 109 !(previous->layoutObject()->style()->contain() & ContainsStyle) |
110 ? previous->layoutObject() | 110 ? previous->layoutObject() |
111 : nullptr; | 111 : nullptr; |
112 } | 112 } |
113 | 113 |
114 static inline Element* parentElement(LayoutObject& object) { | 114 static inline Element* parentElement(LayoutObject& object) { |
115 return toElement(object.node())->parentElement(); | 115 return toElement(object.node())->parentElement(); |
116 } | 116 } |
117 | 117 |
118 static inline bool areLayoutObjectsElementsSiblings(LayoutObject& first, | 118 static inline bool areLayoutObjectsElementsSiblings(LayoutObject& first, |
119 LayoutObject& second) { | 119 LayoutObject& second) { |
120 return parentElement(first) == parentElement(second); | 120 return parentElement(first) == parentElement(second); |
121 } | 121 } |
122 | 122 |
123 // This function processes the layoutObject tree in the order of the DOM tree | 123 // This function processes the layoutObject tree in the order of the DOM tree |
124 // including pseudo elements as defined in CSS 2.1. | 124 // including pseudo elements as defined in CSS 2.1. |
125 static LayoutObject* nextInPreOrder(const LayoutObject& object, | 125 static LayoutObject* nextInPreOrder(const LayoutObject& object, |
126 const Element* stayWithin, | 126 const Element* stayWithin, |
127 bool skipDescendants = false) { | 127 bool skipDescendants = false) { |
128 Element* self = toElement(object.node()); | 128 Element* self = toElement(object.node()); |
129 ASSERT(self); | 129 DCHECK(self); |
130 Element* next = | 130 Element* next = |
131 skipDescendants | 131 skipDescendants |
132 ? ElementTraversal::nextIncludingPseudoSkippingChildren(*self, | 132 ? ElementTraversal::nextIncludingPseudoSkippingChildren(*self, |
133 stayWithin) | 133 stayWithin) |
134 : ElementTraversal::nextIncludingPseudo(*self, stayWithin); | 134 : ElementTraversal::nextIncludingPseudo(*self, stayWithin); |
135 while (next && !next->layoutObject()) | 135 while (next && !next->layoutObject()) |
136 next = skipDescendants | 136 next = skipDescendants |
137 ? ElementTraversal::nextIncludingPseudoSkippingChildren( | 137 ? ElementTraversal::nextIncludingPseudoSkippingChildren( |
138 *next, stayWithin) | 138 *next, stayWithin) |
139 : ElementTraversal::nextIncludingPseudo(*next, stayWithin); | 139 : ElementTraversal::nextIncludingPseudo(*next, stayWithin); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
433 m_nextForSameCounter(nullptr) { | 433 m_nextForSameCounter(nullptr) { |
434 setDocumentForAnonymous(&pseudo.document()); | 434 setDocumentForAnonymous(&pseudo.document()); |
435 view()->addLayoutCounter(); | 435 view()->addLayoutCounter(); |
436 } | 436 } |
437 | 437 |
438 LayoutCounter::~LayoutCounter() {} | 438 LayoutCounter::~LayoutCounter() {} |
439 | 439 |
440 void LayoutCounter::willBeDestroyed() { | 440 void LayoutCounter::willBeDestroyed() { |
441 if (m_counterNode) { | 441 if (m_counterNode) { |
442 m_counterNode->removeLayoutObject(this); | 442 m_counterNode->removeLayoutObject(this); |
443 ASSERT(!m_counterNode); | 443 DCHECK(!m_counterNode); |
444 } | 444 } |
445 if (view()) | 445 if (view()) |
446 view()->removeLayoutCounter(); | 446 view()->removeLayoutCounter(); |
447 LayoutText::willBeDestroyed(); | 447 LayoutText::willBeDestroyed(); |
448 } | 448 } |
449 | 449 |
450 PassRefPtr<StringImpl> LayoutCounter::originalText() const { | 450 PassRefPtr<StringImpl> LayoutCounter::originalText() const { |
451 if (!m_counterNode) { | 451 if (!m_counterNode) { |
452 LayoutObject* beforeAfterContainer = parent(); | 452 LayoutObject* beforeAfterContainer = parent(); |
453 while (true) { | 453 while (true) { |
454 if (!beforeAfterContainer) | 454 if (!beforeAfterContainer) |
455 return nullptr; | 455 return nullptr; |
456 if (!beforeAfterContainer->isAnonymous() && | 456 if (!beforeAfterContainer->isAnonymous() && |
457 !beforeAfterContainer->isPseudoElement()) | 457 !beforeAfterContainer->isPseudoElement()) |
458 return nullptr; // LayoutCounters are restricted to before and after | 458 return nullptr; // LayoutCounters are restricted to before and after |
459 // pseudo elements | 459 // pseudo elements |
460 PseudoId containerStyle = beforeAfterContainer->style()->styleType(); | 460 PseudoId containerStyle = beforeAfterContainer->style()->styleType(); |
461 if ((containerStyle == PseudoIdBefore) || | 461 if ((containerStyle == PseudoIdBefore) || |
462 (containerStyle == PseudoIdAfter)) | 462 (containerStyle == PseudoIdAfter)) |
463 break; | 463 break; |
464 beforeAfterContainer = beforeAfterContainer->parent(); | 464 beforeAfterContainer = beforeAfterContainer->parent(); |
465 } | 465 } |
466 makeCounterNodeIfNeeded(*beforeAfterContainer, m_counter.identifier(), true) | 466 makeCounterNodeIfNeeded(*beforeAfterContainer, m_counter.identifier(), true) |
467 ->addLayoutObject(const_cast<LayoutCounter*>(this)); | 467 ->addLayoutObject(const_cast<LayoutCounter*>(this)); |
468 ASSERT(m_counterNode); | 468 DCHECK(m_counterNode); |
469 } | 469 } |
470 CounterNode* child = m_counterNode; | 470 CounterNode* child = m_counterNode; |
471 int value = child->actsAsReset() ? child->value() : child->countInParent(); | 471 int value = child->actsAsReset() ? child->value() : child->countInParent(); |
472 | 472 |
473 String text = ListMarkerText::text(m_counter.listStyle(), value); | 473 String text = ListMarkerText::text(m_counter.listStyle(), value); |
474 | 474 |
475 if (!m_counter.separator().isNull()) { | 475 if (!m_counter.separator().isNull()) { |
476 if (!child->actsAsReset()) | 476 if (!child->actsAsReset()) |
477 child = child->parent(); | 477 child = child->parent(); |
478 while (CounterNode* parent = child->parent()) { | 478 while (CounterNode* parent = child->parent()) { |
479 text = | 479 text = |
480 ListMarkerText::text(m_counter.listStyle(), child->countInParent()) + | 480 ListMarkerText::text(m_counter.listStyle(), child->countInParent()) + |
481 m_counter.separator() + text; | 481 m_counter.separator() + text; |
482 child = parent; | 482 child = parent; |
483 } | 483 } |
484 } | 484 } |
485 | 485 |
486 return text.impl(); | 486 return text.impl(); |
487 } | 487 } |
488 | 488 |
489 void LayoutCounter::updateCounter() { | 489 void LayoutCounter::updateCounter() { |
490 setText(originalText()); | 490 setText(originalText()); |
491 } | 491 } |
492 | 492 |
493 void LayoutCounter::invalidate() { | 493 void LayoutCounter::invalidate() { |
494 m_counterNode->removeLayoutObject(this); | 494 m_counterNode->removeLayoutObject(this); |
495 ASSERT(!m_counterNode); | 495 DCHECK(!m_counterNode); |
496 if (documentBeingDestroyed()) | 496 if (documentBeingDestroyed()) |
497 return; | 497 return; |
498 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( | 498 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( |
499 LayoutInvalidationReason::CountersChanged); | 499 LayoutInvalidationReason::CountersChanged); |
500 } | 500 } |
501 | 501 |
502 static void destroyCounterNodeWithoutMapRemoval(const AtomicString& identifier, | 502 static void destroyCounterNodeWithoutMapRemoval(const AtomicString& identifier, |
503 CounterNode* node) { | 503 CounterNode* node) { |
504 CounterNode* previous; | 504 CounterNode* previous; |
505 for (RefPtr<CounterNode> child = node->lastDescendant(); | 505 for (RefPtr<CounterNode> child = node->lastDescendant(); |
506 child && child != node; child = previous) { | 506 child && child != node; child = previous) { |
507 previous = child->previousInPreOrder(); | 507 previous = child->previousInPreOrder(); |
508 child->parent()->removeChild(child.get()); | 508 child->parent()->removeChild(child.get()); |
509 ASSERT(counterMaps().at(&child->owner())->at(identifier) == child); | 509 DCHECK(counterMaps().at(&child->owner())->at(identifier) == child); |
tkent
2017/04/04 01:36:17
Use DCHECK_EQ if it doesn't cause a compile failur
mrunal
2017/04/05 00:39:14
Not possible because of compile failure.
| |
510 counterMaps().at(&child->owner())->erase(identifier); | 510 counterMaps().at(&child->owner())->erase(identifier); |
511 } | 511 } |
512 if (CounterNode* parent = node->parent()) | 512 if (CounterNode* parent = node->parent()) |
513 parent->removeChild(node); | 513 parent->removeChild(node); |
514 } | 514 } |
515 | 515 |
516 void LayoutCounter::destroyCounterNodes(LayoutObject& owner) { | 516 void LayoutCounter::destroyCounterNodes(LayoutObject& owner) { |
517 CounterMaps& maps = counterMaps(); | 517 CounterMaps& maps = counterMaps(); |
518 CounterMaps::iterator mapsIterator = maps.find(&owner); | 518 CounterMaps::iterator mapsIterator = maps.find(&owner); |
519 if (mapsIterator == maps.end()) | 519 if (mapsIterator == maps.end()) |
(...skipping 25 matching lines...) Expand all Loading... | |
545 // The destruction of the LayoutObject (possibly caused by the removal of its | 545 // The destruction of the LayoutObject (possibly caused by the removal of its |
546 // associated DOM node) is the other case that leads to the permanent | 546 // associated DOM node) is the other case that leads to the permanent |
547 // destruction of all counters attached to a LayoutObject. In this case | 547 // destruction of all counters attached to a LayoutObject. In this case |
548 // LayoutCounter::destroyCounterNodes() must be and is now called, too. | 548 // LayoutCounter::destroyCounterNodes() must be and is now called, too. |
549 // LayoutCounter::destroyCounterNodes() handles destruction of the counter | 549 // LayoutCounter::destroyCounterNodes() handles destruction of the counter |
550 // map associated with a layoutObject, so there is no risk in leaking the map. | 550 // map associated with a layoutObject, so there is no risk in leaking the map. |
551 } | 551 } |
552 | 552 |
553 void LayoutCounter::layoutObjectSubtreeWillBeDetached( | 553 void LayoutCounter::layoutObjectSubtreeWillBeDetached( |
554 LayoutObject* layoutObject) { | 554 LayoutObject* layoutObject) { |
555 ASSERT(layoutObject->view()); | 555 DCHECK(layoutObject->view()); |
556 // View should never be non-zero. crbug.com/546939 | 556 // View should never be non-zero. crbug.com/546939 |
557 if (!layoutObject->view() || !layoutObject->view()->hasLayoutCounters()) | 557 if (!layoutObject->view() || !layoutObject->view()->hasLayoutCounters()) |
558 return; | 558 return; |
559 | 559 |
560 LayoutObject* currentLayoutObject = layoutObject->lastLeafChild(); | 560 LayoutObject* currentLayoutObject = layoutObject->lastLeafChild(); |
561 if (!currentLayoutObject) | 561 if (!currentLayoutObject) |
562 currentLayoutObject = layoutObject; | 562 currentLayoutObject = layoutObject; |
563 while (true) { | 563 while (true) { |
564 destroyCounterNodes(*currentLayoutObject); | 564 destroyCounterNodes(*currentLayoutObject); |
565 if (currentLayoutObject == layoutObject) | 565 if (currentLayoutObject == layoutObject) |
566 break; | 566 break; |
567 currentLayoutObject = currentLayoutObject->previousInPreOrder(); | 567 currentLayoutObject = currentLayoutObject->previousInPreOrder(); |
568 } | 568 } |
569 } | 569 } |
570 | 570 |
571 static void updateCounters(LayoutObject& layoutObject) { | 571 static void updateCounters(LayoutObject& layoutObject) { |
572 ASSERT(layoutObject.style()); | 572 DCHECK(layoutObject.style()); |
573 const CounterDirectiveMap* directiveMap = | 573 const CounterDirectiveMap* directiveMap = |
574 layoutObject.style()->counterDirectives(); | 574 layoutObject.style()->counterDirectives(); |
575 if (!directiveMap) | 575 if (!directiveMap) |
576 return; | 576 return; |
577 CounterDirectiveMap::const_iterator end = directiveMap->end(); | 577 CounterDirectiveMap::const_iterator end = directiveMap->end(); |
578 if (!layoutObject.hasCounterNodeMap()) { | 578 if (!layoutObject.hasCounterNodeMap()) { |
579 for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); | 579 for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); |
580 it != end; ++it) | 580 it != end; ++it) |
581 makeCounterNodeIfNeeded(layoutObject, it->key, false); | 581 makeCounterNodeIfNeeded(layoutObject, it->key, false); |
582 return; | 582 return; |
583 } | 583 } |
584 CounterMap* counterMap = counterMaps().at(&layoutObject); | 584 CounterMap* counterMap = counterMaps().at(&layoutObject); |
585 ASSERT(counterMap); | 585 DCHECK(counterMap); |
586 for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); | 586 for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); |
587 it != end; ++it) { | 587 it != end; ++it) { |
588 RefPtr<CounterNode> node = counterMap->at(it->key); | 588 RefPtr<CounterNode> node = counterMap->at(it->key); |
589 if (!node) { | 589 if (!node) { |
590 makeCounterNodeIfNeeded(layoutObject, it->key, false); | 590 makeCounterNodeIfNeeded(layoutObject, it->key, false); |
591 continue; | 591 continue; |
592 } | 592 } |
593 RefPtr<CounterNode> newParent = nullptr; | 593 RefPtr<CounterNode> newParent = nullptr; |
594 RefPtr<CounterNode> newPreviousSibling = nullptr; | 594 RefPtr<CounterNode> newPreviousSibling = nullptr; |
595 | 595 |
596 findPlaceForCounter(layoutObject, it->key, node->hasResetType(), newParent, | 596 findPlaceForCounter(layoutObject, it->key, node->hasResetType(), newParent, |
597 newPreviousSibling); | 597 newPreviousSibling); |
598 if (node != counterMap->at(it->key)) | 598 if (node != counterMap->at(it->key)) |
599 continue; | 599 continue; |
600 CounterNode* parent = node->parent(); | 600 CounterNode* parent = node->parent(); |
601 if (newParent == parent && newPreviousSibling == node->previousSibling()) | 601 if (newParent == parent && newPreviousSibling == node->previousSibling()) |
602 continue; | 602 continue; |
603 if (parent) | 603 if (parent) |
604 parent->removeChild(node.get()); | 604 parent->removeChild(node.get()); |
605 if (newParent) | 605 if (newParent) |
606 newParent->insertAfter(node.get(), newPreviousSibling.get(), it->key); | 606 newParent->insertAfter(node.get(), newPreviousSibling.get(), it->key); |
607 } | 607 } |
608 } | 608 } |
609 | 609 |
610 void LayoutCounter::layoutObjectSubtreeAttached(LayoutObject* layoutObject) { | 610 void LayoutCounter::layoutObjectSubtreeAttached(LayoutObject* layoutObject) { |
611 ASSERT(layoutObject->view()); | 611 DCHECK(layoutObject->view()); |
612 if (!layoutObject->view()->hasLayoutCounters()) | 612 if (!layoutObject->view()->hasLayoutCounters()) |
613 return; | 613 return; |
614 Node* node = layoutObject->node(); | 614 Node* node = layoutObject->node(); |
615 if (node) | 615 if (node) |
616 node = node->parentNode(); | 616 node = node->parentNode(); |
617 else | 617 else |
618 node = layoutObject->generatingNode(); | 618 node = layoutObject->generatingNode(); |
619 if (node && node->needsAttach()) | 619 if (node && node->needsAttach()) |
620 return; // No need to update if the parent is not attached yet | 620 return; // No need to update if the parent is not attached yet |
621 for (LayoutObject* descendant = layoutObject; descendant; | 621 for (LayoutObject* descendant = layoutObject; descendant; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
707 current->nextSibling(), | 707 current->nextSibling(), |
708 current->hasCounterNodeMap() | 708 current->hasCounterNodeMap() |
709 ? counterName ? blink::counterMaps().at(current)->at(identifier) | 709 ? counterName ? blink::counterMaps().at(current)->at(identifier) |
710 : (blink::CounterNode*)1 | 710 : (blink::CounterNode*)1 |
711 : (blink::CounterNode*)0); | 711 : (blink::CounterNode*)0); |
712 } | 712 } |
713 fflush(stderr); | 713 fflush(stderr); |
714 } | 714 } |
715 | 715 |
716 #endif // NDEBUG | 716 #endif // NDEBUG |
OLD | NEW |