| 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 * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved. | 4 * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved. |
| 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) | 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 return firstNode; | 136 return firstNode; |
| 137 } | 137 } |
| 138 | 138 |
| 139 // Returns the next list item with respect to the DOM order. | 139 // Returns the next list item with respect to the DOM order. |
| 140 static LayoutListItem* nextListItem(const Node* listNode, | 140 static LayoutListItem* nextListItem(const Node* listNode, |
| 141 const LayoutListItem* item = nullptr) { | 141 const LayoutListItem* item = nullptr) { |
| 142 if (!listNode) | 142 if (!listNode) |
| 143 return nullptr; | 143 return nullptr; |
| 144 | 144 |
| 145 const Node* current = item ? item->node() : listNode; | 145 const Node* current = item ? item->node() : listNode; |
| 146 ASSERT(current); | 146 DCHECK(current); |
| 147 ASSERT(!current->document().childNeedsDistributionRecalc()); | 147 DCHECK(!current->document().childNeedsDistributionRecalc()); |
| 148 current = LayoutTreeBuilderTraversal::next(*current, listNode); | 148 current = LayoutTreeBuilderTraversal::next(*current, listNode); |
| 149 | 149 |
| 150 while (current) { | 150 while (current) { |
| 151 if (isList(*current)) { | 151 if (isList(*current)) { |
| 152 // We've found a nested, independent list: nothing to do here. | 152 // We've found a nested, independent list: nothing to do here. |
| 153 current = | 153 current = |
| 154 LayoutTreeBuilderTraversal::nextSkippingChildren(*current, listNode); | 154 LayoutTreeBuilderTraversal::nextSkippingChildren(*current, listNode); |
| 155 continue; | 155 continue; |
| 156 } | 156 } |
| 157 | 157 |
| 158 LayoutObject* layoutObject = current->layoutObject(); | 158 LayoutObject* layoutObject = current->layoutObject(); |
| 159 if (layoutObject && layoutObject->isListItem()) | 159 if (layoutObject && layoutObject->isListItem()) |
| 160 return toLayoutListItem(layoutObject); | 160 return toLayoutListItem(layoutObject); |
| 161 | 161 |
| 162 // FIXME: Can this be optimized to skip the children of the elements without | 162 // FIXME: Can this be optimized to skip the children of the elements without |
| 163 // a layoutObject? | 163 // a layoutObject? |
| 164 current = LayoutTreeBuilderTraversal::next(*current, listNode); | 164 current = LayoutTreeBuilderTraversal::next(*current, listNode); |
| 165 } | 165 } |
| 166 | 166 |
| 167 return nullptr; | 167 return nullptr; |
| 168 } | 168 } |
| 169 | 169 |
| 170 // Returns the previous list item with respect to the DOM order. | 170 // Returns the previous list item with respect to the DOM order. |
| 171 static LayoutListItem* previousListItem(const Node* listNode, | 171 static LayoutListItem* previousListItem(const Node* listNode, |
| 172 const LayoutListItem* item) { | 172 const LayoutListItem* item) { |
| 173 Node* current = item->node(); | 173 Node* current = item->node(); |
| 174 ASSERT(current); | 174 DCHECK(current); |
| 175 ASSERT(!current->document().childNeedsDistributionRecalc()); | 175 DCHECK(!current->document().childNeedsDistributionRecalc()); |
| 176 for (current = LayoutTreeBuilderTraversal::previous(*current, listNode); | 176 for (current = LayoutTreeBuilderTraversal::previous(*current, listNode); |
| 177 current && current != listNode; | 177 current && current != listNode; |
| 178 current = LayoutTreeBuilderTraversal::previous(*current, listNode)) { | 178 current = LayoutTreeBuilderTraversal::previous(*current, listNode)) { |
| 179 LayoutObject* layoutObject = current->layoutObject(); | 179 LayoutObject* layoutObject = current->layoutObject(); |
| 180 if (!layoutObject || (layoutObject && !layoutObject->isListItem())) | 180 if (!layoutObject || (layoutObject && !layoutObject->isListItem())) |
| 181 continue; | 181 continue; |
| 182 Node* otherList = enclosingList(toLayoutListItem(layoutObject)); | 182 Node* otherList = enclosingList(toLayoutListItem(layoutObject)); |
| 183 // This item is part of our current list, so it's what we're looking for. | 183 // This item is part of our current list, so it's what we're looking for. |
| 184 if (listNode == otherList) | 184 if (listNode == otherList) |
| 185 return toLayoutListItem(layoutObject); | 185 return toLayoutListItem(layoutObject); |
| 186 // We found ourself inside another list; lets skip the rest of it. | 186 // We found ourself inside another list; lets skip the rest of it. |
| 187 // Use nextIncludingPseudo() here because the other list itself may actually | 187 // Use nextIncludingPseudo() here because the other list itself may actually |
| 188 // be a list item itself. We need to examine it, so we do this to counteract | 188 // be a list item itself. We need to examine it, so we do this to counteract |
| 189 // the previousIncludingPseudo() that will be done by the loop. | 189 // the previousIncludingPseudo() that will be done by the loop. |
| 190 if (otherList) | 190 if (otherList) |
| 191 current = LayoutTreeBuilderTraversal::next(*otherList, listNode); | 191 current = LayoutTreeBuilderTraversal::next(*otherList, listNode); |
| 192 } | 192 } |
| 193 return nullptr; | 193 return nullptr; |
| 194 } | 194 } |
| 195 | 195 |
| 196 void LayoutListItem::updateItemValuesForOrderedList( | 196 void LayoutListItem::updateItemValuesForOrderedList( |
| 197 const HTMLOListElement* listNode) { | 197 const HTMLOListElement* listNode) { |
| 198 ASSERT(listNode); | 198 DCHECK(listNode); |
| 199 | 199 |
| 200 for (LayoutListItem* listItem = nextListItem(listNode); listItem; | 200 for (LayoutListItem* listItem = nextListItem(listNode); listItem; |
| 201 listItem = nextListItem(listNode, listItem)) | 201 listItem = nextListItem(listNode, listItem)) |
| 202 listItem->updateValue(); | 202 listItem->updateValue(); |
| 203 } | 203 } |
| 204 | 204 |
| 205 unsigned LayoutListItem::itemCountForOrderedList( | 205 unsigned LayoutListItem::itemCountForOrderedList( |
| 206 const HTMLOListElement* listNode) { | 206 const HTMLOListElement* listNode) { |
| 207 ASSERT(listNode); | 207 DCHECK(listNode); |
| 208 | 208 |
| 209 unsigned itemCount = 0; | 209 unsigned itemCount = 0; |
| 210 for (LayoutListItem* listItem = nextListItem(listNode); listItem; | 210 for (LayoutListItem* listItem = nextListItem(listNode); listItem; |
| 211 listItem = nextListItem(listNode, listItem)) | 211 listItem = nextListItem(listNode, listItem)) |
| 212 itemCount++; | 212 itemCount++; |
| 213 | 213 |
| 214 return itemCount; | 214 return itemCount; |
| 215 } | 215 } |
| 216 | 216 |
| 217 inline int LayoutListItem::calcValue() const { | 217 inline int LayoutListItem::calcValue() const { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 } | 298 } |
| 299 | 299 |
| 300 static LayoutObject* firstNonMarkerChild(LayoutObject* parent) { | 300 static LayoutObject* firstNonMarkerChild(LayoutObject* parent) { |
| 301 LayoutObject* result = parent->slowFirstChild(); | 301 LayoutObject* result = parent->slowFirstChild(); |
| 302 while (result && result->isListMarker()) | 302 while (result && result->isListMarker()) |
| 303 result = result->nextSibling(); | 303 result = result->nextSibling(); |
| 304 return result; | 304 return result; |
| 305 } | 305 } |
| 306 | 306 |
| 307 bool LayoutListItem::updateMarkerLocation() { | 307 bool LayoutListItem::updateMarkerLocation() { |
| 308 ASSERT(m_marker); | 308 DCHECK(m_marker); |
| 309 | 309 |
| 310 LayoutObject* markerParent = m_marker->parent(); | 310 LayoutObject* markerParent = m_marker->parent(); |
| 311 // list-style-position:inside makes the ::marker pseudo an ordinary | 311 // list-style-position:inside makes the ::marker pseudo an ordinary |
| 312 // position:static element that should be attached to LayoutListItem block. | 312 // position:static element that should be attached to LayoutListItem block. |
| 313 LayoutObject* lineBoxParent = | 313 LayoutObject* lineBoxParent = |
| 314 m_marker->isInside() ? this : getParentOfFirstLineBox(this, m_marker); | 314 m_marker->isInside() ? this : getParentOfFirstLineBox(this, m_marker); |
| 315 if (!lineBoxParent) { | 315 if (!lineBoxParent) { |
| 316 // If the marker is currently contained inside an anonymous box, then we | 316 // If the marker is currently contained inside an anonymous box, then we |
| 317 // are the only item in that anonymous box (since no line box parent was | 317 // are the only item in that anonymous box (since no line box parent was |
| 318 // found). It's ok to just leave the marker where it is in this case. | 318 // found). It's ok to just leave the marker where it is in this case. |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 void LayoutListItem::explicitValueChanged() { | 475 void LayoutListItem::explicitValueChanged() { |
| 476 if (m_marker) | 476 if (m_marker) |
| 477 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( | 477 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( |
| 478 LayoutInvalidationReason::ListValueChange); | 478 LayoutInvalidationReason::ListValueChange); |
| 479 Node* listNode = enclosingList(this); | 479 Node* listNode = enclosingList(this); |
| 480 for (LayoutListItem* item = this; item; item = nextListItem(listNode, item)) | 480 for (LayoutListItem* item = this; item; item = nextListItem(listNode, item)) |
| 481 item->updateValue(); | 481 item->updateValue(); |
| 482 } | 482 } |
| 483 | 483 |
| 484 void LayoutListItem::setExplicitValue(int value) { | 484 void LayoutListItem::setExplicitValue(int value) { |
| 485 ASSERT(node()); | 485 DCHECK(node()); |
| 486 | 486 |
| 487 if (m_hasExplicitValue && m_explicitValue == value) | 487 if (m_hasExplicitValue && m_explicitValue == value) |
| 488 return; | 488 return; |
| 489 m_explicitValue = value; | 489 m_explicitValue = value; |
| 490 m_value = value; | 490 m_value = value; |
| 491 m_hasExplicitValue = true; | 491 m_hasExplicitValue = true; |
| 492 explicitValueChanged(); | 492 explicitValueChanged(); |
| 493 } | 493 } |
| 494 | 494 |
| 495 void LayoutListItem::clearExplicitValue() { | 495 void LayoutListItem::clearExplicitValue() { |
| 496 ASSERT(node()); | 496 DCHECK(node()); |
| 497 | 497 |
| 498 if (!m_hasExplicitValue) | 498 if (!m_hasExplicitValue) |
| 499 return; | 499 return; |
| 500 m_hasExplicitValue = false; | 500 m_hasExplicitValue = false; |
| 501 m_isValueUpToDate = false; | 501 m_isValueUpToDate = false; |
| 502 explicitValueChanged(); | 502 explicitValueChanged(); |
| 503 } | 503 } |
| 504 | 504 |
| 505 void LayoutListItem::setNotInList(bool notInList) { | 505 void LayoutListItem::setNotInList(bool notInList) { |
| 506 m_notInList = notInList; | 506 m_notInList = notInList; |
| 507 } | 507 } |
| 508 | 508 |
| 509 static LayoutListItem* previousOrNextItem(bool isListReversed, | 509 static LayoutListItem* previousOrNextItem(bool isListReversed, |
| 510 Node* list, | 510 Node* list, |
| 511 LayoutListItem* item) { | 511 LayoutListItem* item) { |
| 512 return isListReversed ? previousListItem(list, item) | 512 return isListReversed ? previousListItem(list, item) |
| 513 : nextListItem(list, item); | 513 : nextListItem(list, item); |
| 514 } | 514 } |
| 515 | 515 |
| 516 void LayoutListItem::updateListMarkerNumbers() { | 516 void LayoutListItem::updateListMarkerNumbers() { |
| 517 // If distribution recalc is needed, updateListMarkerNumber will be re-invoked | 517 // If distribution recalc is needed, updateListMarkerNumber will be re-invoked |
| 518 // after distribution is calculated. | 518 // after distribution is calculated. |
| 519 if (node()->document().childNeedsDistributionRecalc()) | 519 if (node()->document().childNeedsDistributionRecalc()) |
| 520 return; | 520 return; |
| 521 | 521 |
| 522 Node* listNode = enclosingList(this); | 522 Node* listNode = enclosingList(this); |
| 523 ASSERT(listNode); | 523 DCHECK(listNode); |
| 524 | 524 |
| 525 bool isListReversed = false; | 525 bool isListReversed = false; |
| 526 HTMLOListElement* oListElement = | 526 HTMLOListElement* oListElement = |
| 527 isHTMLOListElement(listNode) ? toHTMLOListElement(listNode) : 0; | 527 isHTMLOListElement(listNode) ? toHTMLOListElement(listNode) : 0; |
| 528 if (oListElement) { | 528 if (oListElement) { |
| 529 oListElement->itemCountChanged(); | 529 oListElement->itemCountChanged(); |
| 530 isListReversed = oListElement->isReversed(); | 530 isListReversed = oListElement->isReversed(); |
| 531 } | 531 } |
| 532 | 532 |
| 533 // FIXME: The n^2 protection below doesn't help if the elements were inserted | 533 // FIXME: The n^2 protection below doesn't help if the elements were inserted |
| (...skipping 12 matching lines...) Expand all Loading... |
| 546 // assume that all the following ones have too. | 546 // assume that all the following ones have too. |
| 547 // This gives us the opportunity to stop here and avoid | 547 // This gives us the opportunity to stop here and avoid |
| 548 // marking the same nodes again. | 548 // marking the same nodes again. |
| 549 break; | 549 break; |
| 550 } | 550 } |
| 551 item->updateValue(); | 551 item->updateValue(); |
| 552 } | 552 } |
| 553 } | 553 } |
| 554 | 554 |
| 555 } // namespace blink | 555 } // namespace blink |
| OLD | NEW |