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

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

Issue 778003003: List marker pseudo elements. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 8 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
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.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details. 15 * Library General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Library General Public License 17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to 18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA. 20 * Boston, MA 02110-1301, USA.
21 * 21 *
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/MarkerPseudoElement.h"
28 #include "core/dom/shadow/ComposedTreeTraversal.h" 29 #include "core/dom/shadow/ComposedTreeTraversal.h"
29 #include "core/html/HTMLOListElement.h" 30 #include "core/html/HTMLOListElement.h"
30 #include "core/layout/LayoutListMarker.h" 31 #include "core/layout/LayoutListMarker.h"
31 #include "core/layout/LayoutView.h" 32 #include "core/layout/LayoutView.h"
32 #include "core/layout/TextAutosizer.h" 33 #include "core/layout/TextAutosizer.h"
33 #include "wtf/StdLibExtras.h" 34 #include "wtf/StdLibExtras.h"
35 #include "wtf/TemporaryChange.h"
34 #include "wtf/text/StringBuilder.h" 36 #include "wtf/text/StringBuilder.h"
35 37
36 namespace blink { 38 namespace blink {
37 39
38 using namespace HTMLNames; 40 using namespace HTMLNames;
39 41
40 LayoutListItem::LayoutListItem(Element* element) 42 LayoutListItem::LayoutListItem(Element* element)
41 : LayoutBlockFlow(element) 43 : LayoutBlockFlow(element)
42 , m_marker(nullptr) 44 , m_marker(nullptr)
43 , m_hasExplicitValue(false) 45 , m_hasExplicitValue(false)
44 , m_isValueUpToDate(false) 46 , m_isValueUpToDate(false)
45 , m_notInList(false) 47 , m_notInList(false)
46 { 48 {
47 setInline(false); 49 setInline(false);
48 } 50 }
49 51
50 void LayoutListItem::styleDidChange(StyleDifference diff, const ComputedStyle* o ldStyle) 52 void LayoutListItem::styleDidChange(StyleDifference diff, const ComputedStyle* o ldStyle)
51 { 53 {
52 LayoutBlockFlow::styleDidChange(diff, oldStyle); 54 LayoutBlockFlow::styleDidChange(diff, oldStyle);
53 55
56 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled())
57 return;
58
54 if (style()->listStyleType() != NoneListStyle 59 if (style()->listStyleType() != NoneListStyle
55 || (style()->listStyleImage() && !style()->listStyleImage()->errorOccurr ed())) { 60 || (style()->listStyleImage() && !style()->listStyleImage()->errorOccurr ed())) {
56 if (!m_marker) 61 if (!m_marker)
57 m_marker = LayoutListMarker::createAnonymous(this); 62 m_marker = LayoutListMarker::createAnonymous(this);
58 m_marker->listItemStyleDidChange(); 63 m_marker->listItemStyleDidChange();
59 } else if (m_marker) { 64 } else if (m_marker) {
60 m_marker->destroy(); 65 m_marker->destroy();
61 m_marker = nullptr; 66 m_marker = nullptr;
62 } 67 }
63 } 68 }
64 69
65 void LayoutListItem::willBeDestroyed() 70 void LayoutListItem::willBeDestroyed()
66 { 71 {
67 if (m_marker) { 72 if (m_marker) {
68 m_marker->destroy(); 73 m_marker->destroy();
69 m_marker = nullptr; 74 m_marker = nullptr;
70 } 75 }
71 LayoutBlockFlow::willBeDestroyed(); 76 LayoutBlockFlow::willBeDestroyed();
72 } 77 }
73 78
74 void LayoutListItem::insertedIntoTree() 79 void LayoutListItem::insertedIntoTree()
75 { 80 {
76 LayoutBlockFlow::insertedIntoTree(); 81 LayoutBlockFlow::insertedIntoTree();
77
78 updateListMarkerNumbers(); 82 updateListMarkerNumbers();
79 } 83 }
80 84
81 void LayoutListItem::willBeRemovedFromTree() 85 void LayoutListItem::willBeRemovedFromTree()
82 { 86 {
83 LayoutBlockFlow::willBeRemovedFromTree(); 87 LayoutBlockFlow::willBeRemovedFromTree();
88 updateListMarkerNumbers();
89 }
84 90
85 updateListMarkerNumbers(); 91 // FIXME: This causes subtree modifications, which will set the flags and we'll
92 // end up doing the check a second time next frame ....
93 void LayoutListItem::handleSubtreeModifications()
94 {
95 if (documentBeingDestroyed())
96 return;
97
98 if (!notifyAncestorsOfSubtreeChange())
esprehn 2015/04/22 07:45:46 The tree walk should handle this for you, not the
dsinclair 2015/04/22 20:00:39 Done.
99 return;
100
101 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER))
esprehn 2015/04/22 07:45:46 Having the layout tree reach back into the DOM lik
dsinclair 2015/04/22 20:00:39 I'm not sure how to fix this one? The PseudoElemen
102 toMarkerPseudoElement(element)->attachListMarkerLayoutObject();
103
104 LayoutBlockFlow::handleSubtreeModifications();
esprehn 2015/04/22 07:45:46 tree walk should be external to the notification c
dsinclair 2015/04/22 20:00:39 Done.
86 } 105 }
87 106
88 static bool isList(const Node& node) 107 static bool isList(const Node& node)
89 { 108 {
90 return isHTMLUListElement(node) || isHTMLOListElement(node); 109 return isHTMLUListElement(node) || isHTMLOListElement(node);
91 } 110 }
92 111
93 // Returns the enclosing list with respect to the DOM order. 112 // Returns the enclosing list with respect to the DOM order.
94 static Node* enclosingList(const LayoutListItem* listItem) 113 static Node* enclosingList(const LayoutListItem* listItem)
95 { 114 {
(...skipping 26 matching lines...) Expand all
122 ASSERT(!current->document().childNeedsDistributionRecalc()); 141 ASSERT(!current->document().childNeedsDistributionRecalc());
123 current = LayoutTreeBuilderTraversal::next(*current, listNode); 142 current = LayoutTreeBuilderTraversal::next(*current, listNode);
124 143
125 while (current) { 144 while (current) {
126 if (isList(*current)) { 145 if (isList(*current)) {
127 // We've found a nested, independent list: nothing to do here. 146 // We've found a nested, independent list: nothing to do here.
128 current = LayoutTreeBuilderTraversal::nextSkippingChildren(*current, listNode); 147 current = LayoutTreeBuilderTraversal::nextSkippingChildren(*current, listNode);
129 continue; 148 continue;
130 } 149 }
131 150
132 LayoutObject* renderer = current->layoutObject(); 151 LayoutObject* layoutObject = current->layoutObject();
133 if (renderer && renderer->isListItem()) 152 if (layoutObject && layoutObject->isListItem())
134 return toLayoutListItem(renderer); 153 return toLayoutListItem(layoutObject);
135 154
136 // FIXME: Can this be optimized to skip the children of the elements wit hout a renderer? 155 // FIXME: Can this be optimized to skip the children of the elements wit hout a layoutObject?
137 current = LayoutTreeBuilderTraversal::next(*current, listNode); 156 current = LayoutTreeBuilderTraversal::next(*current, listNode);
138 } 157 }
139 158
140 return 0; 159 return 0;
141 } 160 }
142 161
143 // Returns the previous list item with respect to the DOM order. 162 // Returns the previous list item with respect to the DOM order.
144 static LayoutListItem* previousListItem(const Node* listNode, const LayoutListIt em* item) 163 static LayoutListItem* previousListItem(const Node* listNode, const LayoutListIt em* item)
145 { 164 {
146 Node* current = item->node(); 165 Node* current = item->node();
147 ASSERT(current); 166 ASSERT(current);
148 ASSERT(!current->document().childNeedsDistributionRecalc()); 167 ASSERT(!current->document().childNeedsDistributionRecalc());
149 for (current = LayoutTreeBuilderTraversal::previous(*current, listNode); cur rent && current != listNode; current = LayoutTreeBuilderTraversal::previous(*cur rent, listNode)) { 168 for (current = LayoutTreeBuilderTraversal::previous(*current, listNode);
150 LayoutObject* renderer = current->layoutObject(); 169 current && current != listNode;
151 if (!renderer || (renderer && !renderer->isListItem())) 170 current = LayoutTreeBuilderTraversal::previous(*current, listNode)) {
171
172 LayoutObject* layoutObject = current->layoutObject();
173 if (!layoutObject || (layoutObject && !layoutObject->isListItem()))
152 continue; 174 continue;
153 Node* otherList = enclosingList(toLayoutListItem(renderer)); 175 Node* otherList = enclosingList(toLayoutListItem(layoutObject));
esprehn 2015/04/22 07:45:46 I'm really not sure all this is a code improvement
dsinclair 2015/04/22 20:00:39 Ack.
154 // This item is part of our current list, so it's what we're looking for . 176 // This item is part of our current list, so it's what we're looking for .
155 if (listNode == otherList) 177 if (listNode == otherList)
156 return toLayoutListItem(renderer); 178 return toLayoutListItem(layoutObject);
157 // We found ourself inside another list; lets skip the rest of it. 179 // We found ourself inside another list; lets skip the rest of it.
158 // Use nextIncludingPseudo() here because the other list itself may actu ally 180 // Use nextIncludingPseudo() here because the other list itself may actu ally
159 // be a list item itself. We need to examine it, so we do this to counte ract 181 // be a list item itself. We need to examine it, so we do this to counte ract
160 // the previousIncludingPseudo() that will be done by the loop. 182 // the previousIncludingPseudo() that will be done by the loop.
161 if (otherList) 183 if (otherList)
162 current = LayoutTreeBuilderTraversal::next(*otherList, listNode); 184 current = LayoutTreeBuilderTraversal::next(*otherList, listNode);
163 } 185 }
164 return 0; 186 return 0;
165 } 187 }
166 188
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 } 228 }
207 229
208 void LayoutListItem::updateValueNow() const 230 void LayoutListItem::updateValueNow() const
209 { 231 {
210 m_value = calcValue(); 232 m_value = calcValue();
211 m_isValueUpToDate = true; 233 m_isValueUpToDate = true;
212 } 234 }
213 235
214 bool LayoutListItem::isEmpty() const 236 bool LayoutListItem::isEmpty() const
215 { 237 {
238 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
239 PseudoElement* element = toElement(node())->pseudoElement(MARKER);
240 return !(element && lastChild() != element->layoutObject());
esprehn 2015/04/22 07:45:46 Run demorgans.
dsinclair 2015/04/22 20:00:39 Done.
241 }
216 return lastChild() == m_marker; 242 return lastChild() == m_marker;
217 } 243 }
218 244
219 static LayoutObject* getParentOfFirstLineBox(LayoutBlockFlow* curr, LayoutObject * marker)
220 {
221 LayoutObject* firstChild = curr->firstChild();
222 if (!firstChild)
223 return 0;
224
225 bool inQuirksMode = curr->document().inQuirksMode();
226 for (LayoutObject* currChild = firstChild; currChild; currChild = currChild- >nextSibling()) {
227 if (currChild == marker)
228 continue;
229
230 if (currChild->isInline() && (!currChild->isLayoutInline() || curr->gene ratesLineBoxesForInlineChild(currChild)))
231 return curr;
232
233 if (currChild->isFloating() || currChild->isOutOfFlowPositioned())
234 continue;
235
236 if (!currChild->isLayoutBlockFlow() || (currChild->isBox() && toLayoutBo x(currChild)->isWritingModeRoot()))
237 break;
238
239 if (curr->isListItem() && inQuirksMode && currChild->node()
240 && (isHTMLUListElement(*currChild->node()) || isHTMLOListElement(*cu rrChild->node())))
241 break;
242
243 LayoutObject* lineBox = getParentOfFirstLineBox(toLayoutBlockFlow(currCh ild), marker);
244 if (lineBox)
245 return lineBox;
246 }
247
248 return 0;
249 }
250
251 void LayoutListItem::updateValue() 245 void LayoutListItem::updateValue()
252 { 246 {
253 if (!m_hasExplicitValue) { 247 if (m_hasExplicitValue)
254 m_isValueUpToDate = false; 248 return;
255 if (m_marker) 249
256 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( LayoutInvalidationReason::ListValueChange); 250 m_isValueUpToDate = false;
251
252 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
253 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER))
254 element->layoutObject()->setNeedsLayoutAndPrefWidthsRecalcAndFullPai ntInvalidation(LayoutInvalidationReason::ListValueChange);
255 } else if (m_marker) {
256 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(Layo utInvalidationReason::ListValueChange);
257 } 257 }
258 } 258 }
259 259
260 static LayoutObject* firstNonMarkerChild(LayoutObject* parent)
261 {
262 LayoutObject* result = parent->slowFirstChild();
263 while (result && result->isListMarker())
264 result = result->nextSibling();
265 return result;
266 }
267
268 void LayoutListItem::updateMarkerLocationAndInvalidateWidth() 260 void LayoutListItem::updateMarkerLocationAndInvalidateWidth()
269 { 261 {
262 ASSERT(!RuntimeEnabledFeatures::listMarkerPseudoElementEnabled());
270 ASSERT(m_marker); 263 ASSERT(m_marker);
271 264
272 // FIXME: We should not modify the structure of the render tree 265 // FIXME: We should not modify the structure of the render tree
273 // during layout. crbug.com/370461 266 // during layout. crbug.com/370461
274 DeprecatedDisableModifyRenderTreeStructureAsserts disabler; 267 DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
275 LayoutState* layoutState = view()->layoutState(); 268 LayoutState* layoutState = view()->layoutState();
276 LayoutFlowThread* currentFlowThread = nullptr; 269 LayoutFlowThread* currentFlowThread = nullptr;
277 if (layoutState) { 270 if (layoutState) {
278 // We're about to modify the layout tree structure (during layout!), and any code using 271 // 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 272 // 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 273 // than the flow thread code will suffer, though, so just reset the curr ent flow thread
281 // temporarily. 274 // temporarily.
282 // FIXME: get rid of this hack, including the flow thread setter in Layo utState, as part of 275 // FIXME: get rid of this hack, including the flow thread setter in Layo utState, as part of
283 // fixing crbug.com/370461 276 // fixing crbug.com/370461
284 currentFlowThread = layoutState->flowThread(); 277 currentFlowThread = layoutState->flowThread();
285 layoutState->setFlowThread(nullptr); 278 layoutState->setFlowThread(nullptr);
286 } 279 }
287 if (updateMarkerLocation()) { 280 if (updateMarkerLocation()) {
288 // If the marker is inside we need to redo the preferred width calculati ons 281 // 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. 282 // as the size of the item now includes the size of the list marker.
290 if (m_marker->isInside()) 283 if (m_marker->isInside())
291 containingBlock()->updateLogicalWidth(); 284 containingBlock()->updateLogicalWidth();
292 } 285 }
293 if (layoutState) 286 if (layoutState)
294 layoutState->setFlowThread(currentFlowThread); 287 layoutState->setFlowThread(currentFlowThread);
295 } 288 }
296 289
297 bool LayoutListItem::updateMarkerLocation() 290 bool LayoutListItem::updateMarkerLocation()
298 { 291 {
292 ASSERT(!RuntimeEnabledFeatures::listMarkerPseudoElementEnabled());
299 ASSERT(m_marker); 293 ASSERT(m_marker);
294
300 LayoutObject* markerParent = m_marker->parent(); 295 LayoutObject* markerParent = m_marker->parent();
301 LayoutObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker); 296 LayoutObject* lineBoxParent = MarkerPseudoElement::parentOfFirstLineBox(this , m_marker);
302 if (!lineBoxParent) { 297 if (!lineBoxParent) {
303 // If the marker is currently contained inside an anonymous box, then we 298 // 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 299 // 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. 300 // found). It's ok to just leave the marker where it is in this case.
306 if (markerParent && markerParent->isAnonymousBlock()) 301 if (markerParent && markerParent->isAnonymousBlock())
307 lineBoxParent = markerParent; 302 lineBoxParent = markerParent;
308 else 303 else
309 lineBoxParent = this; 304 lineBoxParent = this;
310 } 305 }
311 306
312 if (markerParent != lineBoxParent) { 307 if (markerParent != lineBoxParent) {
313 m_marker->remove(); 308 m_marker->remove();
314 lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent)); 309 lineBoxParent->addChild(m_marker, MarkerPseudoElement::firstNonMarkerChi ld(lineBoxParent));
315 m_marker->updateMarginsAndContent(); 310 m_marker->updateMarginsAndContent();
316 // If markerParent is an anonymous block with no children, destroy it. 311 // If markerParent is an anonymous block with no children, destroy it.
317 if (markerParent && markerParent->isAnonymousBlock() && !toLayoutBlock(m arkerParent)->firstChild() && !toLayoutBlock(markerParent)->continuation()) 312 if (markerParent && markerParent->isAnonymousBlock() && !toLayoutBlock(m arkerParent)->firstChild()
313 && !toLayoutBlock(markerParent)->continuation())
318 markerParent->destroy(); 314 markerParent->destroy();
319 return true; 315 return true;
320 } 316 }
321 317
322 return false; 318 return false;
323 } 319 }
324 320
325 void LayoutListItem::layout() 321 void LayoutListItem::layout()
326 { 322 {
327 ASSERT(needsLayout()); 323 ASSERT(needsLayout());
328 324
329 if (m_marker) { 325 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
326 PseudoElement* element = toElement(node())->pseudoElement(MARKER);
esprehn 2015/04/22 07:45:46 I think you just want to keep m_marker, going out
dsinclair 2015/04/22 20:00:39 Done.
327 if (element && element->layoutObject()) {
esprehn 2015/04/22 07:45:46 How does the element exist but not have a layoutOb
dsinclair 2015/04/22 20:00:39 Done.
328 ASSERT(element->layoutObject()->isListMarker());
329 LayoutListMarker* marker = toLayoutListMarker(element->layoutObject( ));
330
331 marker->updateMarginsAndContent();
332 }
333
334 } else if (m_marker) {
330 // The marker must be autosized before calling 335 // The marker must be autosized before calling
331 // updateMarkerLocationAndInvalidateWidth. It cannot be done in the 336 // updateMarkerLocationAndInvalidateWidth. It cannot be done in the
332 // parent's beginLayout because it is not yet in the render tree. 337 // parent's beginLayout because it is not yet in the render tree.
333 if (TextAutosizer* textAutosizer = document().textAutosizer()) 338 if (TextAutosizer* textAutosizer = document().textAutosizer())
334 textAutosizer->inflateListItem(this, m_marker); 339 textAutosizer->inflateListItem(this, m_marker);
335 340
336 updateMarkerLocationAndInvalidateWidth(); 341 updateMarkerLocationAndInvalidateWidth();
337 } 342 }
338 343
339 LayoutBlockFlow::layout(); 344 LayoutBlockFlow::layout();
340 } 345 }
341 346
342 void LayoutListItem::addOverflowFromChildren() 347 void LayoutListItem::addOverflowFromChildren()
343 { 348 {
344 LayoutBlockFlow::addOverflowFromChildren(); 349 LayoutBlockFlow::addOverflowFromChildren();
345 positionListMarker(); 350
351 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
352 MarkerPseudoElement* markerElement = toMarkerPseudoElement(toElement(nod e())->pseudoElement(MARKER));
esprehn 2015/04/22 07:45:46 I really think you want to keep m_marker and not d
dsinclair 2015/04/22 20:00:39 Done.
353 if (markerElement && markerElement->layoutObject()) {
354 ASSERT(markerElement->layoutObject()->isListMarker());
355 positionListMarker(toLayoutListMarker(markerElement->layoutObject()) );
356 }
357 } else {
358 positionListMarker(m_marker);
359 }
346 } 360 }
347 361
348 void LayoutListItem::positionListMarker() 362 void LayoutListItem::positionListMarker(LayoutListMarker* marker)
349 { 363 {
350 if (m_marker && m_marker->parent()->isBox() && !m_marker->isInside() && m_ma rker->inlineBoxWrapper()) { 364 if (!marker)
351 LayoutUnit markerOldLogicalLeft = m_marker->logicalLeft(); 365 return;
366
367 ASSERT(marker->parent());
368 if (marker->parent()->isBox() && !marker->isInside() && marker->inlineBoxWra pper()) {
369 LayoutUnit markerOldLogicalLeft = marker->logicalLeft();
352 LayoutUnit blockOffset = 0; 370 LayoutUnit blockOffset = 0;
353 LayoutUnit lineOffset = 0; 371 LayoutUnit lineOffset = 0;
354 for (LayoutBox* o = m_marker->parentBox(); o != this; o = o->parentBox() ) { 372 for (LayoutBox* o = marker->parentBox(); o != this; o = o->parentBox()) {
355 blockOffset += o->logicalTop(); 373 blockOffset += o->logicalTop();
356 lineOffset += o->logicalLeft(); 374 lineOffset += o->logicalLeft();
357 } 375 }
358 376
359 bool adjustOverflow = false; 377 bool adjustOverflow = false;
360 LayoutUnit markerLogicalLeft; 378 LayoutUnit markerLogicalLeft;
361 RootInlineBox& root = m_marker->inlineBoxWrapper()->root(); 379 RootInlineBox& root = marker->inlineBoxWrapper()->root();
362 bool hitSelfPaintingLayer = false; 380 bool hitSelfPaintingLayer = false;
363 381
364 LayoutUnit lineTop = root.lineTop(); 382 LayoutUnit lineTop = root.lineTop();
365 LayoutUnit lineBottom = root.lineBottom(); 383 LayoutUnit lineBottom = root.lineBottom();
366 384
367 // FIXME: Need to account for relative positioning in the layout overflo w. 385 // FIXME: Need to account for relative positioning in the layout overflo w.
368 if (style()->isLeftToRightDirection()) { 386 if (style()->isLeftToRightDirection()) {
369 LayoutUnit leftLineOffset = logicalLeftOffsetForLine(blockOffset, lo gicalLeftOffsetForLine(blockOffset, false), false); 387 LayoutUnit leftLineOffset = logicalLeftOffsetForLine(blockOffset, lo gicalLeftOffsetForLine(blockOffset, false), false);
370 markerLogicalLeft = leftLineOffset - lineOffset - paddingStart() - b orderStart() + m_marker->marginStart(); 388 markerLogicalLeft = leftLineOffset - lineOffset - paddingStart() - b orderStart() + marker->marginStart();
371 m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLog icalLeft - markerOldLogicalLeft).toFloat()); 389 marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogic alLeft - markerOldLogicalLeft).toFloat());
372 for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); bo x; box = box->parent()) { 390 for (InlineFlowBox* box = marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
373 LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOver flowRect(lineTop, lineBottom); 391 LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOver flowRect(lineTop, lineBottom);
374 LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOver flowRect(lineTop, lineBottom); 392 LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOver flowRect(lineTop, lineBottom);
375 if (markerLogicalLeft < newLogicalVisualOverflowRect.x() && !hit SelfPaintingLayer) { 393 if (markerLogicalLeft < newLogicalVisualOverflowRect.x() && !hit SelfPaintingLayer) {
376 newLogicalVisualOverflowRect.setWidth(newLogicalVisualOverfl owRect.maxX() - markerLogicalLeft); 394 newLogicalVisualOverflowRect.setWidth(newLogicalVisualOverfl owRect.maxX() - markerLogicalLeft);
377 newLogicalVisualOverflowRect.setX(markerLogicalLeft); 395 newLogicalVisualOverflowRect.setX(markerLogicalLeft);
378 if (box == root) 396 if (box == root)
379 adjustOverflow = true; 397 adjustOverflow = true;
380 } 398 }
381 if (markerLogicalLeft < newLogicalLayoutOverflowRect.x()) { 399 if (markerLogicalLeft < newLogicalLayoutOverflowRect.x()) {
382 newLogicalLayoutOverflowRect.setWidth(newLogicalLayoutOverfl owRect.maxX() - markerLogicalLeft); 400 newLogicalLayoutOverflowRect.setWidth(newLogicalLayoutOverfl owRect.maxX() - markerLogicalLeft);
383 newLogicalLayoutOverflowRect.setX(markerLogicalLeft); 401 newLogicalLayoutOverflowRect.setX(markerLogicalLeft);
384 if (box == root) 402 if (box == root)
385 adjustOverflow = true; 403 adjustOverflow = true;
386 } 404 }
387 box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, n ewLogicalVisualOverflowRect, lineTop, lineBottom); 405 box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, n ewLogicalVisualOverflowRect, lineTop, lineBottom);
388 if (box->boxModelObject()->hasSelfPaintingLayer()) 406 if (box->boxModelObject()->hasSelfPaintingLayer())
389 hitSelfPaintingLayer = true; 407 hitSelfPaintingLayer = true;
390 } 408 }
391 } else { 409 } else {
392 LayoutUnit rightLineOffset = logicalRightOffsetForLine(blockOffset, logicalRightOffsetForLine(blockOffset, false), false); 410 LayoutUnit rightLineOffset = logicalRightOffsetForLine(blockOffset, logicalRightOffsetForLine(blockOffset, false), false);
393 markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + m_marker->marginEnd(); 411 markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + marker->marginEnd();
394 m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLog icalLeft - markerOldLogicalLeft).toFloat()); 412 marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogic alLeft - markerOldLogicalLeft).toFloat());
395 for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); bo x; box = box->parent()) { 413 for (InlineFlowBox* box = marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
396 LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOver flowRect(lineTop, lineBottom); 414 LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOver flowRect(lineTop, lineBottom);
397 LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOver flowRect(lineTop, lineBottom); 415 LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOver flowRect(lineTop, lineBottom);
398 if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalVis ualOverflowRect.maxX() && !hitSelfPaintingLayer) { 416 if (markerLogicalLeft + marker->logicalWidth() > newLogicalVisua lOverflowRect.maxX() && !hitSelfPaintingLayer) {
399 newLogicalVisualOverflowRect.setWidth(markerLogicalLeft + m_ marker->logicalWidth() - newLogicalVisualOverflowRect.x()); 417 newLogicalVisualOverflowRect.setWidth(markerLogicalLeft + ma rker->logicalWidth() - newLogicalVisualOverflowRect.x());
400 if (box == root) 418 if (box == root)
401 adjustOverflow = true; 419 adjustOverflow = true;
402 } 420 }
403 if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalLay outOverflowRect.maxX()) { 421 if (markerLogicalLeft + marker->logicalWidth() > newLogicalLayou tOverflowRect.maxX()) {
404 newLogicalLayoutOverflowRect.setWidth(markerLogicalLeft + m_ marker->logicalWidth() - newLogicalLayoutOverflowRect.x()); 422 newLogicalLayoutOverflowRect.setWidth(markerLogicalLeft + ma rker->logicalWidth() - newLogicalLayoutOverflowRect.x());
405 if (box == root) 423 if (box == root)
406 adjustOverflow = true; 424 adjustOverflow = true;
407 } 425 }
408 box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, n ewLogicalVisualOverflowRect, lineTop, lineBottom); 426 box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, n ewLogicalVisualOverflowRect, lineTop, lineBottom);
409 427
410 if (box->boxModelObject()->hasSelfPaintingLayer()) 428 if (box->boxModelObject()->hasSelfPaintingLayer())
411 hitSelfPaintingLayer = true; 429 hitSelfPaintingLayer = true;
412 } 430 }
413 } 431 }
414 432
415 if (adjustOverflow) { 433 if (adjustOverflow) {
416 LayoutRect markerRect(LayoutPoint(markerLogicalLeft + lineOffset, bl ockOffset), m_marker->size()); 434 LayoutRect markerRect(LayoutPoint(markerLogicalLeft + lineOffset, bl ockOffset), marker->size());
417 if (!style()->isHorizontalWritingMode()) 435 if (!style()->isHorizontalWritingMode())
418 markerRect = markerRect.transposedRect(); 436 markerRect = markerRect.transposedRect();
419 LayoutBox* o = m_marker; 437 LayoutBox* o = marker;
420 bool propagateVisualOverflow = true; 438 bool propagateVisualOverflow = true;
421 bool propagateLayoutOverflow = true; 439 bool propagateLayoutOverflow = true;
422 do { 440 do {
423 o = o->parentBox(); 441 o = o->parentBox();
424 if (o->isLayoutBlock()) { 442 if (o->isLayoutBlock()) {
425 if (propagateVisualOverflow) 443 if (propagateVisualOverflow)
426 toLayoutBlock(o)->addContentsVisualOverflow(markerRect); 444 toLayoutBlock(o)->addContentsVisualOverflow(markerRect);
427 if (propagateLayoutOverflow) 445 if (propagateLayoutOverflow)
428 toLayoutBlock(o)->addLayoutOverflow(markerRect); 446 toLayoutBlock(o)->addLayoutOverflow(markerRect);
429 } 447 }
(...skipping 12 matching lines...) Expand all
442 void LayoutListItem::paint(const PaintInfo& paintInfo, const LayoutPoint& paintO ffset) 460 void LayoutListItem::paint(const PaintInfo& paintInfo, const LayoutPoint& paintO ffset)
443 { 461 {
444 if (!logicalHeight() && hasOverflowClip()) 462 if (!logicalHeight() && hasOverflowClip())
445 return; 463 return;
446 464
447 LayoutBlockFlow::paint(paintInfo, paintOffset); 465 LayoutBlockFlow::paint(paintInfo, paintOffset);
448 } 466 }
449 467
450 const String& LayoutListItem::markerText() const 468 const String& LayoutListItem::markerText() const
451 { 469 {
452 if (m_marker) 470 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
471 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER)) {
472 if (element->layoutObject()) {
473 ASSERT(element->layoutObject()->isListMarker());
474 return toLayoutListMarker(element->layoutObject())->text();
esprehn 2015/04/22 07:45:45 ditto.
dsinclair 2015/04/22 20:00:39 Done.
475 }
476 }
477 } else if (m_marker) {
453 return m_marker->text(); 478 return m_marker->text();
479 }
454 return nullAtom.string(); 480 return nullAtom.string();
455 } 481 }
456 482
457 void LayoutListItem::explicitValueChanged() 483 void LayoutListItem::explicitValueChanged()
458 { 484 {
459 if (m_marker) 485 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
486 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER))
487 element->layoutObject()->setNeedsLayoutAndPrefWidthsRecalcAndFullPai ntInvalidation(LayoutInvalidationReason::ListValueChange);
esprehn 2015/04/22 07:45:46 same.
dsinclair 2015/04/22 20:00:39 Done.
488 } else if (m_marker) {
460 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(Layo utInvalidationReason::ListValueChange); 489 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(Layo utInvalidationReason::ListValueChange);
490 }
491
461 Node* listNode = enclosingList(this); 492 Node* listNode = enclosingList(this);
462 for (LayoutListItem* item = this; item; item = nextListItem(listNode, item)) 493 for (LayoutListItem* item = this; item; item = nextListItem(listNode, item))
463 item->updateValue(); 494 item->updateValue();
464 } 495 }
465 496
466 void LayoutListItem::setExplicitValue(int value) 497 void LayoutListItem::setExplicitValue(int value)
467 { 498 {
468 ASSERT(node()); 499 ASSERT(node());
469 500
470 if (m_hasExplicitValue && m_explicitValue == value) 501 if (m_hasExplicitValue && m_explicitValue == value)
(...skipping 11 matching lines...) Expand all
482 if (!m_hasExplicitValue) 513 if (!m_hasExplicitValue)
483 return; 514 return;
484 m_hasExplicitValue = false; 515 m_hasExplicitValue = false;
485 m_isValueUpToDate = false; 516 m_isValueUpToDate = false;
486 explicitValueChanged(); 517 explicitValueChanged();
487 } 518 }
488 519
489 void LayoutListItem::setNotInList(bool notInList) 520 void LayoutListItem::setNotInList(bool notInList)
490 { 521 {
491 m_notInList = notInList; 522 m_notInList = notInList;
492 if (m_marker) 523 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
524 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER)) {
525 ASSERT(element->layoutObject());
526 ASSERT(element->layoutObject()->isListMarker());
527 toLayoutListMarker(element->layoutObject())->updateMarginsAndContent ();
esprehn 2015/04/22 07:45:46 ditto
dsinclair 2015/04/22 20:00:39 Done.
528 }
529 } else if (m_marker) {
493 updateMarkerLocation(); 530 updateMarkerLocation();
531 }
494 } 532 }
495 533
496 static LayoutListItem* previousOrNextItem(bool isListReversed, Node* list, Layou tListItem* item) 534 static LayoutListItem* previousOrNextItem(bool isListReversed, Node* list, Layou tListItem* item)
497 { 535 {
498 return isListReversed ? previousListItem(list, item) : nextListItem(list, it em); 536 return isListReversed ? previousListItem(list, item) : nextListItem(list, it em);
499 } 537 }
500 538
501 void LayoutListItem::updateListMarkerNumbers() 539 void LayoutListItem::updateListMarkerNumbers()
502 { 540 {
503 // If distribution recalc is needed, updateListMarkerNumber will be re-invok ed 541 // 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. 566 // assume that all the following ones have too.
529 // This gives us the opportunity to stop here and avoid 567 // This gives us the opportunity to stop here and avoid
530 // marking the same nodes again. 568 // marking the same nodes again.
531 break; 569 break;
532 } 570 }
533 item->updateValue(); 571 item->updateValue();
534 } 572 }
535 } 573 }
536 574
537 } // namespace blink 575 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698