Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2007 David Smith (catfish.man@gmail.com) | 4 * (C) 2007 David Smith (catfish.man@gmail.com) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. |
| 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 // block. | 91 // block. |
| 92 // | 92 // |
| 93 // This map is populated during layout. It is kept across layouts to handle | 93 // This map is populated during layout. It is kept across layouts to handle |
| 94 // that we skip unchanged sub-trees during layout, in such a way that we are | 94 // that we skip unchanged sub-trees during layout, in such a way that we are |
| 95 // able to lay out deeply nested out-of-flow descendants if their containing | 95 // able to lay out deeply nested out-of-flow descendants if their containing |
| 96 // block got laid out. The map could be invalidated during style change but | 96 // block got laid out. The map could be invalidated during style change but |
| 97 // keeping track of containing blocks at that time is complicated (we are in | 97 // keeping track of containing blocks at that time is complicated (we are in |
| 98 // the middle of recomputing the style so we can't rely on any of its | 98 // the middle of recomputing the style so we can't rely on any of its |
| 99 // information), which is why it's easier to just update it for every layout. | 99 // information), which is why it's easier to just update it for every layout. |
| 100 static TrackedDescendantsMap* gPositionedDescendantsMap = nullptr; | 100 static TrackedDescendantsMap* gPositionedDescendantsMap = nullptr; |
| 101 static TrackedContainerMap* gPositionedContainerMap = nullptr; | |
| 101 | 102 |
| 102 // This map keeps track of the descendants whose 'height' is percentage associat ed | 103 // This map keeps track of the descendants whose 'height' is percentage associat ed |
| 103 // with a containing block. Like |gPositionedDescendantsMap|, it is also recompu ted | 104 // with a containing block. Like |gPositionedDescendantsMap|, it is also recompu ted |
| 104 // for every layout (see the comment above about why). | 105 // for every layout (see the comment above about why). |
| 105 static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr; | 106 static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr; |
| 106 | 107 |
| 107 static TrackedContainerMap* gPositionedContainerMap = nullptr; | |
| 108 static TrackedContainerMap* gPercentHeightContainerMap = nullptr; | |
| 109 | |
| 110 struct ScrollInfo { | 108 struct ScrollInfo { |
| 111 ScrollInfo() : autoHorizontalScrollBarChanged(false), autoVerticalScrollBarC hanged(false) {} | 109 ScrollInfo() : autoHorizontalScrollBarChanged(false), autoVerticalScrollBarC hanged(false) {} |
| 112 DoubleSize scrollOffset; | 110 DoubleSize scrollOffset; |
| 113 bool autoHorizontalScrollBarChanged; | 111 bool autoHorizontalScrollBarChanged; |
| 114 bool autoVerticalScrollBarChanged; | 112 bool autoVerticalScrollBarChanged; |
| 115 bool hasOffset() const { return scrollOffset != DoubleSize(); } | 113 bool hasOffset() const { return scrollOffset != DoubleSize(); } |
| 116 bool scrollBarsChanged() const { return autoHorizontalScrollBarChanged || au toVerticalScrollBarChanged; } | 114 bool scrollBarsChanged() const { return autoHorizontalScrollBarChanged || au toVerticalScrollBarChanged; } |
| 117 void merge(const ScrollInfo& other) | 115 void merge(const ScrollInfo& other) |
| 118 { | 116 { |
| 119 // We always keep the first scrollOffset we saw for this block, so don't copy that field. | 117 // We always keep the first scrollOffset we saw for this block, so don't copy that field. |
| 120 autoHorizontalScrollBarChanged |= other.autoHorizontalScrollBarChanged; | 118 autoHorizontalScrollBarChanged |= other.autoHorizontalScrollBarChanged; |
| 121 autoVerticalScrollBarChanged |= other.autoVerticalScrollBarChanged; | 119 autoVerticalScrollBarChanged |= other.autoVerticalScrollBarChanged; |
| 122 } | 120 } |
| 123 }; | 121 }; |
| 124 typedef WTF::HashMap<LayoutBlock*, ScrollInfo> DelayedUpdateScrollInfoMap; | 122 typedef WTF::HashMap<LayoutBlock*, ScrollInfo> DelayedUpdateScrollInfoMap; |
| 125 static int gDelayUpdateScrollInfo = 0; | 123 static int gDelayUpdateScrollInfo = 0; |
| 126 static DelayedUpdateScrollInfoMap* gDelayedUpdateScrollInfoMap = nullptr; | 124 static DelayedUpdateScrollInfoMap* gDelayedUpdateScrollInfoMap = nullptr; |
| 127 | 125 |
| 128 LayoutBlock::LayoutBlock(ContainerNode* node) | 126 LayoutBlock::LayoutBlock(ContainerNode* node) |
| 129 : LayoutBox(node) | 127 : LayoutBox(node) |
| 130 , m_hasMarginBeforeQuirk(false) | 128 , m_hasMarginBeforeQuirk(false) |
| 131 , m_hasMarginAfterQuirk(false) | 129 , m_hasMarginAfterQuirk(false) |
| 132 , m_beingDestroyed(false) | 130 , m_beingDestroyed(false) |
| 133 , m_hasMarkupTruncation(false) | 131 , m_hasMarkupTruncation(false) |
| 134 , m_widthAvailableToChildrenChanged(false) | 132 , m_widthAvailableToChildrenChanged(false) |
| 135 , m_hasOnlySelfCollapsingChildren(false) | 133 , m_hasOnlySelfCollapsingChildren(false) |
| 136 , m_descendantsWithFloatsMarkedForLayout(false) | 134 , m_descendantsWithFloatsMarkedForLayout(false) |
| 137 , m_needsRecalcLogicalWidthAfterLayoutChildren(false) | 135 , m_needsRecalcLogicalWidthAfterLayoutChildren(false) |
| 136 , m_hasPositionedObjects(false) | |
| 137 , m_hasPercentHeightDescendants(false) | |
| 138 { | 138 { |
| 139 // LayoutBlockFlow calls setChildrenInline(true). | 139 // LayoutBlockFlow calls setChildrenInline(true). |
| 140 // By default, subclasses do not have inline children. | 140 // By default, subclasses do not have inline children. |
| 141 } | 141 } |
| 142 | 142 |
| 143 static void removeBlockFromDescendantAndContainerMaps(LayoutBlock* block, Tracke dDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap) | 143 void LayoutBlock::removeFromGlobalMaps() |
| 144 { | 144 { |
| 145 if (OwnPtr<TrackedLayoutBoxListHashSet> descendantSet = descendantMap->take( block)) { | 145 if (hasPositionedObjects()) { |
| 146 for (auto& descendant : *descendantSet) { | 146 OwnPtr<TrackedLayoutBoxListHashSet> descendants = gPositionedDescendants Map->take(this); |
| 147 TrackedContainerMap::iterator it = containerMap->find(descendant); | 147 ASSERT(!descendants->isEmpty()); |
| 148 ASSERT(it != containerMap->end()); | 148 for (LayoutBox* descendant : *descendants) { |
| 149 if (it == containerMap->end()) | 149 ASSERT(gPositionedContainerMap->get(descendant) == this); |
| 150 continue; | 150 gPositionedContainerMap->remove(descendant); |
| 151 HashSet<LayoutBlock*>* containerSet = it->value.get(); | 151 } |
| 152 ASSERT(containerSet->contains(block)); | 152 } |
| 153 containerSet->remove(block); | 153 if (hasPercentHeightDescendants()) { |
| 154 if (containerSet->isEmpty()) | 154 OwnPtr<TrackedLayoutBoxListHashSet> descendants = gPercentHeightDescenda ntsMap->take(this); |
| 155 containerMap->remove(it); | 155 ASSERT(!descendants->isEmpty()); |
| 156 for (LayoutBox* descendant : *descendants) { | |
| 157 ASSERT(descendant->percentHeightContainer() == this); | |
| 158 descendant->setPercentHeightContainer(nullptr); | |
| 156 } | 159 } |
| 157 } | 160 } |
| 158 } | 161 } |
| 159 | 162 |
| 160 void LayoutBlock::removeFromGlobalMaps() | |
| 161 { | |
| 162 if (gPercentHeightDescendantsMap) | |
| 163 removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendant sMap, gPercentHeightContainerMap); | |
| 164 if (gPositionedDescendantsMap) | |
| 165 removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMa p, gPositionedContainerMap); | |
| 166 } | |
| 167 | |
| 168 LayoutBlock::~LayoutBlock() | 163 LayoutBlock::~LayoutBlock() |
| 169 { | 164 { |
| 170 removeFromGlobalMaps(); | 165 removeFromGlobalMaps(); |
| 171 } | 166 } |
| 172 | 167 |
| 173 void LayoutBlock::willBeDestroyed() | 168 void LayoutBlock::willBeDestroyed() |
| 174 { | 169 { |
| 175 // Mark as being destroyed to avoid trouble with merges in removeChild(). | 170 // Mark as being destroyed to avoid trouble with merges in removeChild(). |
| 176 m_beingDestroyed = true; | 171 m_beingDestroyed = true; |
| 177 | 172 |
| (...skipping 1212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1390 } | 1385 } |
| 1391 | 1386 |
| 1392 void LayoutBlock::setSelectionState(SelectionState state) | 1387 void LayoutBlock::setSelectionState(SelectionState state) |
| 1393 { | 1388 { |
| 1394 LayoutBox::setSelectionState(state); | 1389 LayoutBox::setSelectionState(state); |
| 1395 | 1390 |
| 1396 if (inlineBoxWrapper() && canUpdateSelectionOnRootLineBoxes()) | 1391 if (inlineBoxWrapper() && canUpdateSelectionOnRootLineBoxes()) |
| 1397 inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone ); | 1392 inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone ); |
| 1398 } | 1393 } |
| 1399 | 1394 |
| 1400 void LayoutBlock::insertIntoTrackedLayoutBoxMaps(LayoutBox* descendant, TrackedD escendantsMap*& descendantsMap, TrackedContainerMap*& containerMap) | 1395 TrackedLayoutBoxListHashSet* LayoutBlock::positionedObjectsInternal() const |
| 1401 { | 1396 { |
| 1402 if (!descendantsMap) { | 1397 return gPositionedDescendantsMap ? gPositionedDescendantsMap->get(this) : nu llptr; |
| 1403 descendantsMap = new TrackedDescendantsMap; | |
| 1404 containerMap = new TrackedContainerMap; | |
| 1405 } | |
| 1406 | |
| 1407 TrackedLayoutBoxListHashSet* descendantSet = descendantsMap->get(this); | |
| 1408 if (!descendantSet) { | |
| 1409 descendantSet = new TrackedLayoutBoxListHashSet; | |
| 1410 descendantsMap->set(this, adoptPtr(descendantSet)); | |
| 1411 } | |
| 1412 bool added = descendantSet->add(descendant).isNewEntry; | |
| 1413 if (!added) { | |
| 1414 ASSERT(containerMap->get(descendant)); | |
| 1415 ASSERT(containerMap->get(descendant)->contains(this)); | |
| 1416 return; | |
| 1417 } | |
| 1418 | |
| 1419 HashSet<LayoutBlock*>* containerSet = containerMap->get(descendant); | |
| 1420 if (!containerSet) { | |
| 1421 containerSet = new HashSet<LayoutBlock*>; | |
| 1422 containerMap->set(descendant, adoptPtr(containerSet)); | |
| 1423 } | |
| 1424 ASSERT(!containerSet->contains(this)); | |
| 1425 containerSet->add(this); | |
| 1426 } | |
| 1427 | |
| 1428 void LayoutBlock::removeFromTrackedLayoutBoxMaps(LayoutBox* descendant, TrackedD escendantsMap*& descendantsMap, TrackedContainerMap*& containerMap) | |
| 1429 { | |
| 1430 if (!descendantsMap) | |
| 1431 return; | |
| 1432 | |
| 1433 OwnPtr<HashSet<LayoutBlock*>> containerSet = containerMap->take(descendant); | |
| 1434 if (!containerSet) | |
| 1435 return; | |
| 1436 | |
| 1437 for (auto* container : *containerSet) { | |
| 1438 // FIXME: Disabling this assert temporarily until we fix the layout | |
| 1439 // bugs associated with positioned objects not properly cleared from | |
| 1440 // their ancestor chain before being moved. See webkit bug 93766. | |
| 1441 // ASSERT(descendant->isDescendantOf(container)); | |
| 1442 | |
| 1443 TrackedDescendantsMap::iterator descendantsMapIterator = descendantsMap- >find(container); | |
| 1444 ASSERT(descendantsMapIterator != descendantsMap->end()); | |
| 1445 if (descendantsMapIterator == descendantsMap->end()) | |
| 1446 continue; | |
| 1447 TrackedLayoutBoxListHashSet* descendantSet = descendantsMapIterator->val ue.get(); | |
| 1448 ASSERT(descendantSet->contains(descendant)); | |
| 1449 descendantSet->remove(descendant); | |
| 1450 if (descendantSet->isEmpty()) | |
| 1451 descendantsMap->remove(descendantsMapIterator); | |
| 1452 } | |
| 1453 } | |
| 1454 | |
| 1455 TrackedLayoutBoxListHashSet* LayoutBlock::positionedObjects() const | |
| 1456 { | |
| 1457 if (gPositionedDescendantsMap) | |
| 1458 return gPositionedDescendantsMap->get(this); | |
| 1459 return nullptr; | |
| 1460 } | 1398 } |
| 1461 | 1399 |
| 1462 void LayoutBlock::insertPositionedObject(LayoutBox* o) | 1400 void LayoutBlock::insertPositionedObject(LayoutBox* o) |
| 1463 { | 1401 { |
| 1464 ASSERT(!isAnonymousBlock()); | 1402 ASSERT(!isAnonymousBlock()); |
| 1465 insertIntoTrackedLayoutBoxMaps(o, gPositionedDescendantsMap, gPositionedCont ainerMap); | 1403 ASSERT(o->containingBlock() == this); |
| 1404 | |
| 1405 if (gPositionedContainerMap) { | |
| 1406 auto containerMapIt = gPositionedContainerMap->find(o); | |
| 1407 if (containerMapIt != gPositionedContainerMap->end()) { | |
| 1408 if (containerMapIt->value == this) { | |
| 1409 ASSERT(hasPositionedObjects() && positionedObjects()->contains(o )); | |
| 1410 return; | |
| 1411 } | |
| 1412 removePositionedObject(o); | |
| 1413 } | |
| 1414 } else { | |
| 1415 gPositionedContainerMap = new TrackedContainerMap; | |
| 1416 } | |
| 1417 gPositionedContainerMap->set(o, this); | |
| 1418 | |
| 1419 if (!gPositionedDescendantsMap) | |
| 1420 gPositionedDescendantsMap = new TrackedDescendantsMap; | |
| 1421 TrackedLayoutBoxListHashSet* descendantSet = gPositionedDescendantsMap->get( this); | |
| 1422 if (!descendantSet) { | |
| 1423 descendantSet = new TrackedLayoutBoxListHashSet; | |
| 1424 gPositionedDescendantsMap->set(this, adoptPtr(descendantSet)); | |
| 1425 } | |
| 1426 descendantSet->add(o); | |
| 1427 | |
| 1428 m_hasPositionedObjects = true; | |
| 1466 } | 1429 } |
| 1467 | 1430 |
| 1468 void LayoutBlock::removePositionedObject(LayoutBox* o) | 1431 void LayoutBlock::removePositionedObject(LayoutBox* o) |
| 1469 { | 1432 { |
| 1470 removeFromTrackedLayoutBoxMaps(o, gPositionedDescendantsMap, gPositionedCont ainerMap); | 1433 if (!gPositionedContainerMap) |
| 1434 return; | |
| 1435 | |
| 1436 LayoutBlock* container = gPositionedContainerMap->take(o); | |
| 1437 if (!container) | |
| 1438 return; | |
| 1439 | |
| 1440 TrackedLayoutBoxListHashSet* positionedDescendants = gPositionedDescendantsM ap->get(container); | |
| 1441 ASSERT(positionedDescendants && positionedDescendants->contains(o)); | |
| 1442 positionedDescendants->remove(o); | |
| 1443 if (positionedDescendants->isEmpty()) { | |
| 1444 gPositionedDescendantsMap->remove(container); | |
| 1445 container->m_hasPositionedObjects = false; | |
| 1446 } | |
| 1471 } | 1447 } |
| 1472 | 1448 |
| 1473 void LayoutBlock::removePositionedObjects(LayoutBlock* o, ContainingBlockState c ontainingBlockState) | 1449 void LayoutBlock::removePositionedObjects(LayoutBlock* o, ContainingBlockState c ontainingBlockState) |
| 1474 { | 1450 { |
| 1475 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); | 1451 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); |
| 1476 if (!positionedDescendants) | 1452 if (!positionedDescendants) |
| 1477 return; | 1453 return; |
| 1478 | 1454 |
| 1479 Vector<LayoutBox*, 16> deadObjects; | 1455 Vector<LayoutBox*, 16> deadObjects; |
| 1480 for (auto* positionedObject : *positionedDescendants) { | 1456 for (auto* positionedObject : *positionedDescendants) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1499 LayoutObject* p = positionedObject->parent(); | 1475 LayoutObject* p = positionedObject->parent(); |
| 1500 while (p && !p->isLayoutBlock()) | 1476 while (p && !p->isLayoutBlock()) |
| 1501 p = p->parent(); | 1477 p = p->parent(); |
| 1502 if (p) | 1478 if (p) |
| 1503 p->setChildNeedsLayout(); | 1479 p->setChildNeedsLayout(); |
| 1504 | 1480 |
| 1505 deadObjects.append(positionedObject); | 1481 deadObjects.append(positionedObject); |
| 1506 } | 1482 } |
| 1507 } | 1483 } |
| 1508 | 1484 |
| 1509 for (unsigned i = 0; i < deadObjects.size(); i++) | 1485 for (auto o : deadObjects) { |
|
esprehn
2016/01/25 21:45:04
object?
Xianzhu
2016/01/25 22:09:40
Done.
| |
| 1510 removePositionedObject(deadObjects.at(i)); | 1486 ASSERT(gPositionedContainerMap->get(o) == this); |
| 1487 positionedDescendants->remove(o); | |
| 1488 gPositionedContainerMap->remove(o); | |
| 1489 } | |
| 1490 if (positionedDescendants->isEmpty()) { | |
| 1491 gPositionedDescendantsMap->remove(this); | |
| 1492 m_hasPositionedObjects = false; | |
| 1493 } | |
| 1511 } | 1494 } |
| 1512 | 1495 |
| 1513 void LayoutBlock::addPercentHeightDescendant(LayoutBox* descendant) | 1496 void LayoutBlock::addPercentHeightDescendant(LayoutBox* descendant) |
| 1514 { | 1497 { |
| 1515 insertIntoTrackedLayoutBoxMaps(descendant, gPercentHeightDescendantsMap, gPe rcentHeightContainerMap); | 1498 if (descendant->percentHeightContainer()) { |
| 1499 if (descendant->percentHeightContainer() == this) { | |
| 1500 ASSERT(hasPercentHeightDescendant(descendant)); | |
| 1501 return; | |
| 1502 } | |
| 1503 descendant->removeFromPercentHeightContainer(); | |
| 1504 } | |
| 1505 descendant->setPercentHeightContainer(this); | |
| 1506 | |
| 1507 if (!gPercentHeightDescendantsMap) | |
| 1508 gPercentHeightDescendantsMap = new TrackedDescendantsMap; | |
| 1509 TrackedLayoutBoxListHashSet* descendantSet = gPercentHeightDescendantsMap->g et(this); | |
| 1510 if (!descendantSet) { | |
| 1511 descendantSet = new TrackedLayoutBoxListHashSet; | |
| 1512 gPercentHeightDescendantsMap->set(this, adoptPtr(descendantSet)); | |
| 1513 } | |
| 1514 descendantSet->add(descendant); | |
| 1515 | |
| 1516 m_hasPercentHeightDescendants = true; | |
| 1516 } | 1517 } |
| 1517 | 1518 |
| 1518 void LayoutBlock::removePercentHeightDescendant(LayoutBox* descendant) | 1519 void LayoutBlock::removePercentHeightDescendant(LayoutBox* descendant) |
| 1519 { | 1520 { |
| 1520 removeFromTrackedLayoutBoxMaps(descendant, gPercentHeightDescendantsMap, gPe rcentHeightContainerMap); | 1521 if (TrackedLayoutBoxListHashSet* descendants = percentHeightDescendants()) { |
| 1522 descendants->remove(descendant); | |
| 1523 descendant->setPercentHeightContainer(nullptr); | |
| 1524 if (descendants->isEmpty()) { | |
| 1525 gPercentHeightDescendantsMap->remove(this); | |
| 1526 m_hasPercentHeightDescendants = false; | |
| 1527 } | |
| 1528 } | |
| 1521 } | 1529 } |
| 1522 | 1530 |
| 1523 TrackedLayoutBoxListHashSet* LayoutBlock::percentHeightDescendants() const | 1531 TrackedLayoutBoxListHashSet* LayoutBlock::percentHeightDescendantsInternal() con st |
| 1524 { | 1532 { |
| 1525 return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this ) : 0; | 1533 return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this ) : nullptr; |
| 1526 } | |
| 1527 | |
| 1528 bool LayoutBlock::hasPercentHeightContainerMap() | |
| 1529 { | |
| 1530 return gPercentHeightContainerMap; | |
| 1531 } | |
| 1532 | |
| 1533 bool LayoutBlock::hasPercentHeightDescendant(LayoutBox* descendant) | |
| 1534 { | |
| 1535 // We don't null check gPercentHeightContainerMap since the caller | |
| 1536 // already ensures this and we need to call this function on every | |
| 1537 // descendant in clearPercentHeightDescendantsFrom(). | |
| 1538 ASSERT(gPercentHeightContainerMap); | |
| 1539 return gPercentHeightContainerMap->contains(descendant); | |
| 1540 } | 1534 } |
| 1541 | 1535 |
| 1542 void LayoutBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutSco pe& layoutScope) | 1536 void LayoutBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutSco pe& layoutScope) |
| 1543 { | 1537 { |
| 1544 if (!gPercentHeightDescendantsMap) | 1538 TrackedLayoutBoxListHashSet* descendants = percentHeightDescendants(); |
| 1545 return; | |
| 1546 | |
| 1547 TrackedLayoutBoxListHashSet* descendants = gPercentHeightDescendantsMap->get (this); | |
| 1548 if (!descendants) | 1539 if (!descendants) |
| 1549 return; | 1540 return; |
| 1550 | 1541 |
| 1551 for (auto* box : *descendants) { | 1542 for (auto* box : *descendants) { |
| 1552 ASSERT(box->isDescendantOf(this)); | 1543 ASSERT(box->isDescendantOf(this)); |
| 1553 while (box != this) { | 1544 while (box != this) { |
| 1554 if (box->normalChildNeedsLayout()) | 1545 if (box->normalChildNeedsLayout()) |
| 1555 break; | 1546 break; |
| 1556 layoutScope.setChildNeedsLayout(box); | 1547 layoutScope.setChildNeedsLayout(box); |
| 1557 box = box->containingBlock(); | 1548 box = box->containingBlock(); |
| 1558 ASSERT(box); | 1549 ASSERT(box); |
| 1559 if (!box) | 1550 if (!box) |
| 1560 break; | 1551 break; |
| 1561 } | 1552 } |
| 1562 } | 1553 } |
| 1563 } | 1554 } |
| 1564 | 1555 |
| 1565 void LayoutBlock::removePercentHeightDescendantIfNeeded(LayoutBox* descendant) | |
| 1566 { | |
| 1567 // We query the map directly, rather than looking at style's | |
| 1568 // logicalHeight()/logicalMinHeight()/logicalMaxHeight() since those | |
| 1569 // can change with writing mode/directional changes. | |
| 1570 if (!hasPercentHeightContainerMap()) | |
| 1571 return; | |
| 1572 | |
| 1573 if (!hasPercentHeightDescendant(descendant)) | |
| 1574 return; | |
| 1575 | |
| 1576 removePercentHeightDescendant(descendant); | |
| 1577 } | |
| 1578 | |
| 1579 void LayoutBlock::clearPercentHeightDescendantsFrom(LayoutBox* parent) | |
| 1580 { | |
| 1581 ASSERT(gPercentHeightContainerMap); | |
| 1582 for (LayoutObject* curr = parent->slowFirstChild(); curr; curr = curr->nextI nPreOrder(parent)) { | |
| 1583 if (!curr->isBox()) | |
| 1584 continue; | |
| 1585 | |
| 1586 LayoutBox* box = toLayoutBox(curr); | |
| 1587 if (!hasPercentHeightDescendant(box)) | |
| 1588 continue; | |
| 1589 | |
| 1590 removePercentHeightDescendant(box); | |
| 1591 } | |
| 1592 } | |
| 1593 | |
| 1594 LayoutUnit LayoutBlock::textIndentOffset() const | 1556 LayoutUnit LayoutBlock::textIndentOffset() const |
| 1595 { | 1557 { |
| 1596 LayoutUnit cw = 0; | 1558 LayoutUnit cw = 0; |
| 1597 if (style()->textIndent().hasPercent()) | 1559 if (style()->textIndent().hasPercent()) |
| 1598 cw = containingBlock()->availableLogicalWidth(); | 1560 cw = containingBlock()->availableLogicalWidth(); |
| 1599 return minimumValueForLength(style()->textIndent(), cw); | 1561 return minimumValueForLength(style()->textIndent(), cw); |
| 1600 } | 1562 } |
| 1601 | 1563 |
| 1602 void LayoutBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit l ogicalBottom, RootInlineBox* highest) | 1564 void LayoutBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit l ogicalBottom, RootInlineBox* highest) |
| 1603 { | 1565 { |
| (...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2896 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout Object* obj) const | 2858 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout Object* obj) const |
| 2897 { | 2859 { |
| 2898 showLayoutObject(); | 2860 showLayoutObject(); |
| 2899 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) | 2861 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) |
| 2900 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); | 2862 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); |
| 2901 } | 2863 } |
| 2902 | 2864 |
| 2903 #endif | 2865 #endif |
| 2904 | 2866 |
| 2905 } // namespace blink | 2867 } // namespace blink |
| OLD | NEW |