Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: Source/core/layout/LayoutListItem.cpp

Issue 1110233003: Update list markers in notify change. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Review updates Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/layout/LayoutListItem.h ('k') | Source/core/layout/LayoutState.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11 matching lines...) Expand all
22 */ 22 */
23 23
24 #include "config.h" 24 #include "config.h"
25 #include "core/layout/LayoutListItem.h" 25 #include "core/layout/LayoutListItem.h"
26 26
27 #include "core/HTMLNames.h" 27 #include "core/HTMLNames.h"
28 #include "core/dom/shadow/ComposedTreeTraversal.h" 28 #include "core/dom/shadow/ComposedTreeTraversal.h"
29 #include "core/html/HTMLOListElement.h" 29 #include "core/html/HTMLOListElement.h"
30 #include "core/layout/LayoutListMarker.h" 30 #include "core/layout/LayoutListMarker.h"
31 #include "core/layout/LayoutView.h" 31 #include "core/layout/LayoutView.h"
32 #include "core/layout/TextAutosizer.h"
33 #include "wtf/StdLibExtras.h" 32 #include "wtf/StdLibExtras.h"
34 #include "wtf/text/StringBuilder.h" 33 #include "wtf/text/StringBuilder.h"
35 34
36 namespace blink { 35 namespace blink {
37 36
38 using namespace HTMLNames; 37 using namespace HTMLNames;
39 38
40 LayoutListItem::LayoutListItem(Element* element) 39 LayoutListItem::LayoutListItem(Element* element)
41 : LayoutBlockFlow(element) 40 : LayoutBlockFlow(element)
42 , m_marker(nullptr) 41 , m_marker(nullptr)
43 , m_hasExplicitValue(false) 42 , m_hasExplicitValue(false)
44 , m_isValueUpToDate(false) 43 , m_isValueUpToDate(false)
45 , m_notInList(false) 44 , m_notInList(false)
46 { 45 {
47 setInline(false); 46 setInline(false);
47
48 setConsumesSubtreeChangeNotification();
49 registerSubtreeChangeListenerOnDescendants(true);
50 notifyOfSubtreeChange();
esprehn 2015/05/06 16:10:28 This isn't right though, it's like calling setNeed
48 } 51 }
49 52
50 void LayoutListItem::styleDidChange(StyleDifference diff, const ComputedStyle* o ldStyle) 53 void LayoutListItem::styleDidChange(StyleDifference diff, const ComputedStyle* o ldStyle)
51 { 54 {
52 LayoutBlockFlow::styleDidChange(diff, oldStyle); 55 LayoutBlockFlow::styleDidChange(diff, oldStyle);
53 56
54 if (style()->listStyleType() != NoneListStyle 57 if (style()->listStyleType() != NoneListStyle
55 || (style()->listStyleImage() && !style()->listStyleImage()->errorOccurr ed())) { 58 || (style()->listStyleImage() && !style()->listStyleImage()->errorOccurr ed())) {
56 if (!m_marker) 59 if (!m_marker)
57 m_marker = LayoutListMarker::createAnonymous(this); 60 m_marker = LayoutListMarker::createAnonymous(this);
58 m_marker->listItemStyleDidChange(); 61 m_marker->listItemStyleDidChange();
62 notifyOfSubtreeChange();
59 } else if (m_marker) { 63 } else if (m_marker) {
60 m_marker->destroy(); 64 m_marker->destroy();
61 m_marker = nullptr; 65 m_marker = nullptr;
62 } 66 }
63 } 67 }
64 68
65 void LayoutListItem::willBeDestroyed() 69 void LayoutListItem::willBeDestroyed()
66 { 70 {
67 if (m_marker) { 71 if (m_marker) {
68 m_marker->destroy(); 72 m_marker->destroy();
69 m_marker = nullptr; 73 m_marker = nullptr;
70 } 74 }
71 LayoutBlockFlow::willBeDestroyed(); 75 LayoutBlockFlow::willBeDestroyed();
72 } 76 }
73 77
74 void LayoutListItem::insertedIntoTree() 78 void LayoutListItem::insertedIntoTree()
75 { 79 {
76 LayoutBlockFlow::insertedIntoTree(); 80 LayoutBlockFlow::insertedIntoTree();
77 81
78 updateListMarkerNumbers(); 82 updateListMarkerNumbers();
79 } 83 }
80 84
81 void LayoutListItem::willBeRemovedFromTree() 85 void LayoutListItem::willBeRemovedFromTree()
82 { 86 {
83 LayoutBlockFlow::willBeRemovedFromTree(); 87 LayoutBlockFlow::willBeRemovedFromTree();
84 88
85 updateListMarkerNumbers(); 89 updateListMarkerNumbers();
86 } 90 }
87 91
92 void LayoutListItem::subtreeDidChange()
93 {
94 if (!m_marker)
95 return;
96
97 if (!updateMarkerLocation())
98 return;
99
100 // If the marker is inside we need to redo the preferred width calculations
101 // as the size of the item now includes the size of the list marker.
102 if (m_marker->isInside())
103 setPreferredLogicalWidthsDirty();
104 }
105
88 static bool isList(const Node& node) 106 static bool isList(const Node& node)
89 { 107 {
90 return isHTMLUListElement(node) || isHTMLOListElement(node); 108 return isHTMLUListElement(node) || isHTMLOListElement(node);
91 } 109 }
92 110
93 // Returns the enclosing list with respect to the DOM order. 111 // Returns the enclosing list with respect to the DOM order.
94 static Node* enclosingList(const LayoutListItem* listItem) 112 static Node* enclosingList(const LayoutListItem* listItem)
95 { 113 {
96 Node* listItemNode = listItem->node(); 114 Node* listItemNode = listItem->node();
97 if (!listItemNode) 115 if (!listItemNode)
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 } 276 }
259 277
260 static LayoutObject* firstNonMarkerChild(LayoutObject* parent) 278 static LayoutObject* firstNonMarkerChild(LayoutObject* parent)
261 { 279 {
262 LayoutObject* result = parent->slowFirstChild(); 280 LayoutObject* result = parent->slowFirstChild();
263 while (result && result->isListMarker()) 281 while (result && result->isListMarker())
264 result = result->nextSibling(); 282 result = result->nextSibling();
265 return result; 283 return result;
266 } 284 }
267 285
268 void LayoutListItem::updateMarkerLocationAndInvalidateWidth()
269 {
270 ASSERT(m_marker);
271
272 // FIXME: We should not modify the structure of the layout tree
273 // during layout. crbug.com/370461
274 DeprecatedDisableModifyLayoutTreeStructureAsserts disabler;
275 LayoutState* layoutState = view()->layoutState();
276 LayoutFlowThread* currentFlowThread = nullptr;
277 if (layoutState) {
278 // We're about to modify the layout tree structure (during layout!), and any code using
279 // LayoutState might get utterly confused by that. There's no evidence t hat anything other
280 // than the flow thread code will suffer, though, so just reset the curr ent flow thread
281 // temporarily.
282 // FIXME: get rid of this hack, including the flow thread setter in Layo utState, as part of
283 // fixing crbug.com/370461
284 currentFlowThread = layoutState->flowThread();
285 layoutState->setFlowThread(nullptr);
286 }
287 if (updateMarkerLocation()) {
288 // If the marker is inside we need to redo the preferred width calculati ons
289 // as the size of the item now includes the size of the list marker.
290 if (m_marker->isInside())
291 containingBlock()->updateLogicalWidth();
292 }
293 if (layoutState)
294 layoutState->setFlowThread(currentFlowThread);
295 }
296
297 bool LayoutListItem::updateMarkerLocation() 286 bool LayoutListItem::updateMarkerLocation()
298 { 287 {
299 ASSERT(m_marker); 288 ASSERT(m_marker);
289
300 LayoutObject* markerParent = m_marker->parent(); 290 LayoutObject* markerParent = m_marker->parent();
301 LayoutObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker); 291 LayoutObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker);
302 if (!lineBoxParent) { 292 if (!lineBoxParent) {
303 // If the marker is currently contained inside an anonymous box, then we 293 // If the marker is currently contained inside an anonymous box, then we
304 // are the only item in that anonymous box (since no line box parent was 294 // are the only item in that anonymous box (since no line box parent was
305 // found). It's ok to just leave the marker where it is in this case. 295 // found). It's ok to just leave the marker where it is in this case.
306 if (markerParent && markerParent->isAnonymousBlock()) 296 if (markerParent && markerParent->isAnonymousBlock())
307 lineBoxParent = markerParent; 297 lineBoxParent = markerParent;
308 else 298 else
309 lineBoxParent = this; 299 lineBoxParent = this;
310 } 300 }
311 301
312 if (markerParent != lineBoxParent) { 302 if (markerParent != lineBoxParent) {
313 m_marker->remove(); 303 m_marker->remove();
314 lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent)); 304 lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent));
315 m_marker->updateMarginsAndContent(); 305 m_marker->updateMarginsAndContent();
316 // If markerParent is an anonymous block with no children, destroy it. 306 // If markerParent is an anonymous block with no children, destroy it.
317 if (markerParent && markerParent->isAnonymousBlock() && !toLayoutBlock(m arkerParent)->firstChild() && !toLayoutBlock(markerParent)->continuation()) 307 if (markerParent && markerParent->isAnonymousBlock() && !toLayoutBlock(m arkerParent)->firstChild() && !toLayoutBlock(markerParent)->continuation())
318 markerParent->destroy(); 308 markerParent->destroy();
319 return true; 309 return true;
320 } 310 }
321 311
322 return false; 312 return false;
323 } 313 }
324 314
325 void LayoutListItem::layout()
326 {
327 ASSERT(needsLayout());
328
329 if (m_marker) {
330 // The marker must be autosized before calling
331 // updateMarkerLocationAndInvalidateWidth. It cannot be done in the
332 // parent's beginLayout because it is not yet in the layout tree.
333 if (TextAutosizer* textAutosizer = document().textAutosizer())
334 textAutosizer->inflateListItem(this, m_marker);
335
336 updateMarkerLocationAndInvalidateWidth();
337 }
338
339 LayoutBlockFlow::layout();
340 }
341
342 void LayoutListItem::addOverflowFromChildren() 315 void LayoutListItem::addOverflowFromChildren()
343 { 316 {
344 LayoutBlockFlow::addOverflowFromChildren(); 317 LayoutBlockFlow::addOverflowFromChildren();
345 positionListMarker(); 318 positionListMarker();
346 } 319 }
347 320
348 void LayoutListItem::positionListMarker() 321 void LayoutListItem::positionListMarker()
349 { 322 {
350 if (m_marker && m_marker->parent()->isBox() && !m_marker->isInside() && m_ma rker->inlineBoxWrapper()) { 323 if (m_marker && m_marker->parent() && m_marker->parent()->isBox() && !m_mark er->isInside() && m_marker->inlineBoxWrapper()) {
351 LayoutUnit markerOldLogicalLeft = m_marker->logicalLeft(); 324 LayoutUnit markerOldLogicalLeft = m_marker->logicalLeft();
352 LayoutUnit blockOffset = 0; 325 LayoutUnit blockOffset = 0;
353 LayoutUnit lineOffset = 0; 326 LayoutUnit lineOffset = 0;
354 for (LayoutBox* o = m_marker->parentBox(); o != this; o = o->parentBox() ) { 327 for (LayoutBox* o = m_marker->parentBox(); o != this; o = o->parentBox() ) {
355 blockOffset += o->logicalTop(); 328 blockOffset += o->logicalTop();
356 lineOffset += o->logicalLeft(); 329 lineOffset += o->logicalLeft();
357 } 330 }
358 331
359 bool adjustOverflow = false; 332 bool adjustOverflow = false;
360 LayoutUnit markerLogicalLeft; 333 LayoutUnit markerLogicalLeft;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 if (!m_hasExplicitValue) 455 if (!m_hasExplicitValue)
483 return; 456 return;
484 m_hasExplicitValue = false; 457 m_hasExplicitValue = false;
485 m_isValueUpToDate = false; 458 m_isValueUpToDate = false;
486 explicitValueChanged(); 459 explicitValueChanged();
487 } 460 }
488 461
489 void LayoutListItem::setNotInList(bool notInList) 462 void LayoutListItem::setNotInList(bool notInList)
490 { 463 {
491 m_notInList = notInList; 464 m_notInList = notInList;
492 if (m_marker)
493 updateMarkerLocation();
494 } 465 }
495 466
496 static LayoutListItem* previousOrNextItem(bool isListReversed, Node* list, Layou tListItem* item) 467 static LayoutListItem* previousOrNextItem(bool isListReversed, Node* list, Layou tListItem* item)
497 { 468 {
498 return isListReversed ? previousListItem(list, item) : nextListItem(list, it em); 469 return isListReversed ? previousListItem(list, item) : nextListItem(list, it em);
499 } 470 }
500 471
501 void LayoutListItem::updateListMarkerNumbers() 472 void LayoutListItem::updateListMarkerNumbers()
502 { 473 {
503 // If distribution recalc is needed, updateListMarkerNumber will be re-invok ed 474 // If distribution recalc is needed, updateListMarkerNumber will be re-invok ed
(...skipping 24 matching lines...) Expand all
528 // assume that all the following ones have too. 499 // assume that all the following ones have too.
529 // This gives us the opportunity to stop here and avoid 500 // This gives us the opportunity to stop here and avoid
530 // marking the same nodes again. 501 // marking the same nodes again.
531 break; 502 break;
532 } 503 }
533 item->updateValue(); 504 item->updateValue();
534 } 505 }
535 } 506 }
536 507
537 } // namespace blink 508 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/layout/LayoutListItem.h ('k') | Source/core/layout/LayoutState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698