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 |