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

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)
45 , m_inSubtreeChanged(false)
43 , m_hasExplicitValue(false) 46 , m_hasExplicitValue(false)
44 , m_isValueUpToDate(false) 47 , m_isValueUpToDate(false)
45 , m_notInList(false) 48 , m_notInList(false)
46 { 49 {
47 setInline(false); 50 setInline(false);
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
57 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled())
58 return;
59
54 if (style()->listStyleType() != NoneListStyle 60 if (style()->listStyleType() != NoneListStyle
55 || (style()->listStyleImage() && !style()->listStyleImage()->errorOccurr ed())) { 61 || (style()->listStyleImage() && !style()->listStyleImage()->errorOccurr ed())) {
56 if (!m_marker) 62 if (!m_marker)
57 m_marker = LayoutListMarker::createAnonymous(this); 63 m_marker = LayoutListMarker::createAnonymous(this);
58 m_marker->listItemStyleDidChange(); 64 m_marker->listItemStyleDidChange();
59 } else if (m_marker) { 65 } else if (m_marker) {
60 m_marker->destroy(); 66 m_marker->destroy();
61 m_marker = nullptr; 67 m_marker = nullptr;
62 } 68 }
63 } 69 }
64 70
65 void LayoutListItem::willBeDestroyed() 71 void LayoutListItem::willBeDestroyed()
66 { 72 {
67 if (m_marker) { 73 if (m_marker) {
68 m_marker->destroy(); 74 m_marker->destroy();
69 m_marker = nullptr; 75 m_marker = nullptr;
70 } 76 }
71 LayoutBlockFlow::willBeDestroyed(); 77 LayoutBlockFlow::willBeDestroyed();
72 } 78 }
73 79
74 void LayoutListItem::insertedIntoTree() 80 void LayoutListItem::insertedIntoTree()
75 { 81 {
76 LayoutBlockFlow::insertedIntoTree(); 82 LayoutBlockFlow::insertedIntoTree();
77
78 updateListMarkerNumbers(); 83 updateListMarkerNumbers();
79 } 84 }
80 85
81 void LayoutListItem::willBeRemovedFromTree() 86 void LayoutListItem::willBeRemovedFromTree()
82 { 87 {
83 LayoutBlockFlow::willBeRemovedFromTree(); 88 LayoutBlockFlow::willBeRemovedFromTree();
89 updateListMarkerNumbers();
90 }
84 91
85 updateListMarkerNumbers(); 92 void LayoutListItem::subtreeChangedNotification()
93 {
94 if (!document().lifecycle().isActive())
95 return;
96
97 if (m_inSubtreeChanged)
98 return;
99
100 TemporaryChange<bool> changed(m_inSubtreeChanged, true);
101
esprehn 2015/04/20 16:04:08 This is an example why you can't do this, it's ver
dsinclair 2015/04/21 20:23:10 Done.
102 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER))
esprehn 2015/04/20 16:04:08 You can't do synchronous subtree notifications lik
dsinclair 2015/04/21 20:23:10 Done.
103 toMarkerPseudoElement(element)->attachListMarkerLayoutObject();
104
105 LayoutBlockFlow::subtreeChangedNotification();
106 }
107
108 void LayoutListItem::addChild(LayoutObject* newChild, LayoutObject* beforeChild)
109 {
110 LayoutBlockFlow::addChild(newChild, beforeChild);
111
112 if (!RuntimeEnabledFeatures::listMarkerPseudoElementEnabled())
113 return;
114
115 newChild->setNotifyAncestorsOfSubtreeChangeRecursive(true);
116
117 // If we've inserted a new child we, possibly, have to move the list marker
118 // into that child. Nothing to do if it's the marker we're inserting.
119 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER)) {
120 if (newChild != element->layoutObject())
121 toMarkerPseudoElement(element)->attachListMarkerLayoutObject();
122 }
123 }
124
125 void LayoutListItem::removeChild(LayoutObject* child)
126 {
127 LayoutBlockFlow::removeChild(child);
128
129 if (!RuntimeEnabledFeatures::listMarkerPseudoElementEnabled())
130 return;
131
132 child->setNotifyAncestorsOfSubtreeChangeRecursive(false);
133
134 // If we've removed a child we, possibly, have to move the list marker
135 // into a new parent. Don't try to update the marker when it's the
136 // marker that was removed.
137 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER)) {
138 if (child != element->layoutObject())
139 toMarkerPseudoElement(element)->attachListMarkerLayoutObject();
140 }
86 } 141 }
87 142
88 static bool isList(const Node& node) 143 static bool isList(const Node& node)
89 { 144 {
90 return isHTMLUListElement(node) || isHTMLOListElement(node); 145 return isHTMLUListElement(node) || isHTMLOListElement(node);
91 } 146 }
92 147
93 // Returns the enclosing list with respect to the DOM order. 148 // Returns the enclosing list with respect to the DOM order.
94 static Node* enclosingList(const LayoutListItem* listItem) 149 static Node* enclosingList(const LayoutListItem* listItem)
95 { 150 {
(...skipping 26 matching lines...) Expand all
122 ASSERT(!current->document().childNeedsDistributionRecalc()); 177 ASSERT(!current->document().childNeedsDistributionRecalc());
123 current = LayoutTreeBuilderTraversal::next(*current, listNode); 178 current = LayoutTreeBuilderTraversal::next(*current, listNode);
124 179
125 while (current) { 180 while (current) {
126 if (isList(*current)) { 181 if (isList(*current)) {
127 // We've found a nested, independent list: nothing to do here. 182 // We've found a nested, independent list: nothing to do here.
128 current = LayoutTreeBuilderTraversal::nextSkippingChildren(*current, listNode); 183 current = LayoutTreeBuilderTraversal::nextSkippingChildren(*current, listNode);
129 continue; 184 continue;
130 } 185 }
131 186
132 LayoutObject* renderer = current->layoutObject(); 187 LayoutObject* layoutObject = current->layoutObject();
133 if (renderer && renderer->isListItem()) 188 if (layoutObject && layoutObject->isListItem())
134 return toLayoutListItem(renderer); 189 return toLayoutListItem(layoutObject);
135 190
136 // FIXME: Can this be optimized to skip the children of the elements wit hout a renderer? 191 // FIXME: Can this be optimized to skip the children of the elements wit hout a layoutObject?
137 current = LayoutTreeBuilderTraversal::next(*current, listNode); 192 current = LayoutTreeBuilderTraversal::next(*current, listNode);
138 } 193 }
139 194
140 return 0; 195 return 0;
141 } 196 }
142 197
143 // Returns the previous list item with respect to the DOM order. 198 // Returns the previous list item with respect to the DOM order.
144 static LayoutListItem* previousListItem(const Node* listNode, const LayoutListIt em* item) 199 static LayoutListItem* previousListItem(const Node* listNode, const LayoutListIt em* item)
145 { 200 {
146 Node* current = item->node(); 201 Node* current = item->node();
147 ASSERT(current); 202 ASSERT(current);
148 ASSERT(!current->document().childNeedsDistributionRecalc()); 203 ASSERT(!current->document().childNeedsDistributionRecalc());
149 for (current = LayoutTreeBuilderTraversal::previous(*current, listNode); cur rent && current != listNode; current = LayoutTreeBuilderTraversal::previous(*cur rent, listNode)) { 204 for (current = LayoutTreeBuilderTraversal::previous(*current, listNode);
150 LayoutObject* renderer = current->layoutObject(); 205 current && current != listNode;
151 if (!renderer || (renderer && !renderer->isListItem())) 206 current = LayoutTreeBuilderTraversal::previous(*current, listNode)) {
207
208 LayoutObject* layoutObject = current->layoutObject();
209 if (!layoutObject || (layoutObject && !layoutObject->isListItem()))
152 continue; 210 continue;
153 Node* otherList = enclosingList(toLayoutListItem(renderer)); 211 Node* otherList = enclosingList(toLayoutListItem(layoutObject));
154 // This item is part of our current list, so it's what we're looking for . 212 // This item is part of our current list, so it's what we're looking for .
155 if (listNode == otherList) 213 if (listNode == otherList)
156 return toLayoutListItem(renderer); 214 return toLayoutListItem(layoutObject);
157 // We found ourself inside another list; lets skip the rest of it. 215 // We found ourself inside another list; lets skip the rest of it.
158 // Use nextIncludingPseudo() here because the other list itself may actu ally 216 // 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 217 // 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. 218 // the previousIncludingPseudo() that will be done by the loop.
161 if (otherList) 219 if (otherList)
162 current = LayoutTreeBuilderTraversal::next(*otherList, listNode); 220 current = LayoutTreeBuilderTraversal::next(*otherList, listNode);
163 } 221 }
164 return 0; 222 return 0;
165 } 223 }
166 224
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 } 264 }
207 265
208 void LayoutListItem::updateValueNow() const 266 void LayoutListItem::updateValueNow() const
209 { 267 {
210 m_value = calcValue(); 268 m_value = calcValue();
211 m_isValueUpToDate = true; 269 m_isValueUpToDate = true;
212 } 270 }
213 271
214 bool LayoutListItem::isEmpty() const 272 bool LayoutListItem::isEmpty() const
215 { 273 {
274 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
275 PseudoElement* element = toElement(node())->pseudoElement(MARKER);
276 return !(element && lastChild() != element->layoutObject());
277 }
216 return lastChild() == m_marker; 278 return lastChild() == m_marker;
217 } 279 }
218 280
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() 281 void LayoutListItem::updateValue()
252 { 282 {
253 if (!m_hasExplicitValue) { 283 if (m_hasExplicitValue)
254 m_isValueUpToDate = false; 284 return;
255 if (m_marker) 285
256 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( LayoutInvalidationReason::ListValueChange); 286 m_isValueUpToDate = false;
287
288 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
289 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER))
290 element->layoutObject()->setNeedsLayoutAndPrefWidthsRecalcAndFullPai ntInvalidation(LayoutInvalidationReason::ListValueChange);
291 } else if (m_marker) {
292 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(Layo utInvalidationReason::ListValueChange);
257 } 293 }
258 } 294 }
259 295
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() 296 void LayoutListItem::updateMarkerLocationAndInvalidateWidth()
269 { 297 {
298 ASSERT(!RuntimeEnabledFeatures::listMarkerPseudoElementEnabled());
270 ASSERT(m_marker); 299 ASSERT(m_marker);
271 300
272 // FIXME: We should not modify the structure of the render tree 301 // FIXME: We should not modify the structure of the render tree
273 // during layout. crbug.com/370461 302 // during layout. crbug.com/370461
274 DeprecatedDisableModifyRenderTreeStructureAsserts disabler; 303 DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
275 LayoutState* layoutState = view()->layoutState(); 304 LayoutState* layoutState = view()->layoutState();
276 LayoutFlowThread* currentFlowThread = nullptr; 305 LayoutFlowThread* currentFlowThread = nullptr;
277 if (layoutState) { 306 if (layoutState) {
278 // We're about to modify the layout tree structure (during layout!), and any code using 307 // 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 308 // 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 309 // than the flow thread code will suffer, though, so just reset the curr ent flow thread
281 // temporarily. 310 // temporarily.
282 // FIXME: get rid of this hack, including the flow thread setter in Layo utState, as part of 311 // FIXME: get rid of this hack, including the flow thread setter in Layo utState, as part of
283 // fixing crbug.com/370461 312 // fixing crbug.com/370461
284 currentFlowThread = layoutState->flowThread(); 313 currentFlowThread = layoutState->flowThread();
285 layoutState->setFlowThread(nullptr); 314 layoutState->setFlowThread(nullptr);
286 } 315 }
287 if (updateMarkerLocation()) { 316 if (updateMarkerLocation()) {
288 // If the marker is inside we need to redo the preferred width calculati ons 317 // 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. 318 // as the size of the item now includes the size of the list marker.
290 if (m_marker->isInside()) 319 if (m_marker->isInside())
291 containingBlock()->updateLogicalWidth(); 320 containingBlock()->updateLogicalWidth();
292 } 321 }
293 if (layoutState) 322 if (layoutState)
294 layoutState->setFlowThread(currentFlowThread); 323 layoutState->setFlowThread(currentFlowThread);
295 } 324 }
296 325
297 bool LayoutListItem::updateMarkerLocation() 326 bool LayoutListItem::updateMarkerLocation()
298 { 327 {
328 ASSERT(!RuntimeEnabledFeatures::listMarkerPseudoElementEnabled());
299 ASSERT(m_marker); 329 ASSERT(m_marker);
330
300 LayoutObject* markerParent = m_marker->parent(); 331 LayoutObject* markerParent = m_marker->parent();
301 LayoutObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker); 332 LayoutObject* lineBoxParent = MarkerPseudoElement::getParentOfFirstLineBox(t his, m_marker);
302 if (!lineBoxParent) { 333 if (!lineBoxParent) {
303 // If the marker is currently contained inside an anonymous box, then we 334 // 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 335 // 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. 336 // found). It's ok to just leave the marker where it is in this case.
306 if (markerParent && markerParent->isAnonymousBlock()) 337 if (markerParent && markerParent->isAnonymousBlock())
307 lineBoxParent = markerParent; 338 lineBoxParent = markerParent;
308 else 339 else
309 lineBoxParent = this; 340 lineBoxParent = this;
310 } 341 }
311 342
312 if (markerParent != lineBoxParent) { 343 if (markerParent != lineBoxParent) {
313 m_marker->remove(); 344 m_marker->remove();
314 lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent)); 345 lineBoxParent->addChild(m_marker, MarkerPseudoElement::firstNonMarkerChi ld(lineBoxParent));
315 m_marker->updateMarginsAndContent(); 346 m_marker->updateMarginsAndContent();
316 // If markerParent is an anonymous block with no children, destroy it. 347 // If markerParent is an anonymous block with no children, destroy it.
317 if (markerParent && markerParent->isAnonymousBlock() && !toLayoutBlock(m arkerParent)->firstChild() && !toLayoutBlock(markerParent)->continuation()) 348 if (markerParent && markerParent->isAnonymousBlock() && !toLayoutBlock(m arkerParent)->firstChild()
349 && !toLayoutBlock(markerParent)->continuation())
318 markerParent->destroy(); 350 markerParent->destroy();
319 return true; 351 return true;
320 } 352 }
321 353
322 return false; 354 return false;
323 } 355 }
324 356
325 void LayoutListItem::layout() 357 void LayoutListItem::layout()
326 { 358 {
327 ASSERT(needsLayout()); 359 ASSERT(needsLayout());
328 360
329 if (m_marker) { 361 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
362 PseudoElement* element = toElement(node())->pseudoElement(MARKER);
363 if (element && element->layoutObject()) {
364 ASSERT(element->layoutObject()->isListMarker());
365 LayoutListMarker* marker = toLayoutListMarker(element->layoutObject( ));
366
367 marker->updateMarginsAndContent();
368 }
369
370 } else if (m_marker) {
330 // The marker must be autosized before calling 371 // The marker must be autosized before calling
331 // updateMarkerLocationAndInvalidateWidth. It cannot be done in the 372 // updateMarkerLocationAndInvalidateWidth. It cannot be done in the
332 // parent's beginLayout because it is not yet in the render tree. 373 // parent's beginLayout because it is not yet in the render tree.
333 if (TextAutosizer* textAutosizer = document().textAutosizer()) 374 if (TextAutosizer* textAutosizer = document().textAutosizer())
334 textAutosizer->inflateListItem(this, m_marker); 375 textAutosizer->inflateListItem(this, m_marker);
335 376
336 updateMarkerLocationAndInvalidateWidth(); 377 updateMarkerLocationAndInvalidateWidth();
337 } 378 }
338 379
339 LayoutBlockFlow::layout(); 380 LayoutBlockFlow::layout();
340 } 381 }
341 382
342 void LayoutListItem::addOverflowFromChildren() 383 void LayoutListItem::addOverflowFromChildren()
343 { 384 {
344 LayoutBlockFlow::addOverflowFromChildren(); 385 LayoutBlockFlow::addOverflowFromChildren();
345 positionListMarker(); 386
387 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
388 MarkerPseudoElement* markerElement = toMarkerPseudoElement(toElement(nod e())->pseudoElement(MARKER));
389 if (markerElement && markerElement->layoutObject()) {
390 ASSERT(markerElement->layoutObject()->isListMarker());
391 positionListMarker(toLayoutListMarker(markerElement->layoutObject()) );
392 }
393 } else {
394 positionListMarker(m_marker);
395 }
346 } 396 }
347 397
348 void LayoutListItem::positionListMarker() 398 void LayoutListItem::positionListMarker(LayoutListMarker* marker)
349 { 399 {
350 if (m_marker && m_marker->parent()->isBox() && !m_marker->isInside() && m_ma rker->inlineBoxWrapper()) { 400 if (!marker)
351 LayoutUnit markerOldLogicalLeft = m_marker->logicalLeft(); 401 return;
402
403 ASSERT(marker->parent());
404 if (marker->parent()->isBox() && !marker->isInside() && marker->inlineBoxWra pper()) {
405 LayoutUnit markerOldLogicalLeft = marker->logicalLeft();
352 LayoutUnit blockOffset = 0; 406 LayoutUnit blockOffset = 0;
353 LayoutUnit lineOffset = 0; 407 LayoutUnit lineOffset = 0;
354 for (LayoutBox* o = m_marker->parentBox(); o != this; o = o->parentBox() ) { 408 for (LayoutBox* o = marker->parentBox(); o != this; o = o->parentBox()) {
355 blockOffset += o->logicalTop(); 409 blockOffset += o->logicalTop();
356 lineOffset += o->logicalLeft(); 410 lineOffset += o->logicalLeft();
357 } 411 }
358 412
359 bool adjustOverflow = false; 413 bool adjustOverflow = false;
360 LayoutUnit markerLogicalLeft; 414 LayoutUnit markerLogicalLeft;
361 RootInlineBox& root = m_marker->inlineBoxWrapper()->root(); 415 RootInlineBox& root = marker->inlineBoxWrapper()->root();
362 bool hitSelfPaintingLayer = false; 416 bool hitSelfPaintingLayer = false;
363 417
364 LayoutUnit lineTop = root.lineTop(); 418 LayoutUnit lineTop = root.lineTop();
365 LayoutUnit lineBottom = root.lineBottom(); 419 LayoutUnit lineBottom = root.lineBottom();
366 420
367 // FIXME: Need to account for relative positioning in the layout overflo w. 421 // FIXME: Need to account for relative positioning in the layout overflo w.
368 if (style()->isLeftToRightDirection()) { 422 if (style()->isLeftToRightDirection()) {
369 LayoutUnit leftLineOffset = logicalLeftOffsetForLine(blockOffset, lo gicalLeftOffsetForLine(blockOffset, false), false); 423 LayoutUnit leftLineOffset = logicalLeftOffsetForLine(blockOffset, lo gicalLeftOffsetForLine(blockOffset, false), false);
370 markerLogicalLeft = leftLineOffset - lineOffset - paddingStart() - b orderStart() + m_marker->marginStart(); 424 markerLogicalLeft = leftLineOffset - lineOffset - paddingStart() - b orderStart() + marker->marginStart();
371 m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLog icalLeft - markerOldLogicalLeft).toFloat()); 425 marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogic alLeft - markerOldLogicalLeft).toFloat());
372 for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); bo x; box = box->parent()) { 426 for (InlineFlowBox* box = marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
373 LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOver flowRect(lineTop, lineBottom); 427 LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOver flowRect(lineTop, lineBottom);
374 LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOver flowRect(lineTop, lineBottom); 428 LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOver flowRect(lineTop, lineBottom);
375 if (markerLogicalLeft < newLogicalVisualOverflowRect.x() && !hit SelfPaintingLayer) { 429 if (markerLogicalLeft < newLogicalVisualOverflowRect.x() && !hit SelfPaintingLayer) {
376 newLogicalVisualOverflowRect.setWidth(newLogicalVisualOverfl owRect.maxX() - markerLogicalLeft); 430 newLogicalVisualOverflowRect.setWidth(newLogicalVisualOverfl owRect.maxX() - markerLogicalLeft);
377 newLogicalVisualOverflowRect.setX(markerLogicalLeft); 431 newLogicalVisualOverflowRect.setX(markerLogicalLeft);
378 if (box == root) 432 if (box == root)
379 adjustOverflow = true; 433 adjustOverflow = true;
380 } 434 }
381 if (markerLogicalLeft < newLogicalLayoutOverflowRect.x()) { 435 if (markerLogicalLeft < newLogicalLayoutOverflowRect.x()) {
382 newLogicalLayoutOverflowRect.setWidth(newLogicalLayoutOverfl owRect.maxX() - markerLogicalLeft); 436 newLogicalLayoutOverflowRect.setWidth(newLogicalLayoutOverfl owRect.maxX() - markerLogicalLeft);
383 newLogicalLayoutOverflowRect.setX(markerLogicalLeft); 437 newLogicalLayoutOverflowRect.setX(markerLogicalLeft);
384 if (box == root) 438 if (box == root)
385 adjustOverflow = true; 439 adjustOverflow = true;
386 } 440 }
387 box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, n ewLogicalVisualOverflowRect, lineTop, lineBottom); 441 box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, n ewLogicalVisualOverflowRect, lineTop, lineBottom);
388 if (box->boxModelObject()->hasSelfPaintingLayer()) 442 if (box->boxModelObject()->hasSelfPaintingLayer())
389 hitSelfPaintingLayer = true; 443 hitSelfPaintingLayer = true;
390 } 444 }
391 } else { 445 } else {
392 LayoutUnit rightLineOffset = logicalRightOffsetForLine(blockOffset, logicalRightOffsetForLine(blockOffset, false), false); 446 LayoutUnit rightLineOffset = logicalRightOffsetForLine(blockOffset, logicalRightOffsetForLine(blockOffset, false), false);
393 markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + m_marker->marginEnd(); 447 markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + marker->marginEnd();
394 m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLog icalLeft - markerOldLogicalLeft).toFloat()); 448 marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogic alLeft - markerOldLogicalLeft).toFloat());
395 for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); bo x; box = box->parent()) { 449 for (InlineFlowBox* box = marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
396 LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOver flowRect(lineTop, lineBottom); 450 LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOver flowRect(lineTop, lineBottom);
397 LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOver flowRect(lineTop, lineBottom); 451 LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOver flowRect(lineTop, lineBottom);
398 if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalVis ualOverflowRect.maxX() && !hitSelfPaintingLayer) { 452 if (markerLogicalLeft + marker->logicalWidth() > newLogicalVisua lOverflowRect.maxX() && !hitSelfPaintingLayer) {
399 newLogicalVisualOverflowRect.setWidth(markerLogicalLeft + m_ marker->logicalWidth() - newLogicalVisualOverflowRect.x()); 453 newLogicalVisualOverflowRect.setWidth(markerLogicalLeft + ma rker->logicalWidth() - newLogicalVisualOverflowRect.x());
400 if (box == root) 454 if (box == root)
401 adjustOverflow = true; 455 adjustOverflow = true;
402 } 456 }
403 if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalLay outOverflowRect.maxX()) { 457 if (markerLogicalLeft + marker->logicalWidth() > newLogicalLayou tOverflowRect.maxX()) {
404 newLogicalLayoutOverflowRect.setWidth(markerLogicalLeft + m_ marker->logicalWidth() - newLogicalLayoutOverflowRect.x()); 458 newLogicalLayoutOverflowRect.setWidth(markerLogicalLeft + ma rker->logicalWidth() - newLogicalLayoutOverflowRect.x());
405 if (box == root) 459 if (box == root)
406 adjustOverflow = true; 460 adjustOverflow = true;
407 } 461 }
408 box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, n ewLogicalVisualOverflowRect, lineTop, lineBottom); 462 box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, n ewLogicalVisualOverflowRect, lineTop, lineBottom);
409 463
410 if (box->boxModelObject()->hasSelfPaintingLayer()) 464 if (box->boxModelObject()->hasSelfPaintingLayer())
411 hitSelfPaintingLayer = true; 465 hitSelfPaintingLayer = true;
412 } 466 }
413 } 467 }
414 468
415 if (adjustOverflow) { 469 if (adjustOverflow) {
416 LayoutRect markerRect(LayoutPoint(markerLogicalLeft + lineOffset, bl ockOffset), m_marker->size()); 470 LayoutRect markerRect(LayoutPoint(markerLogicalLeft + lineOffset, bl ockOffset), marker->size());
417 if (!style()->isHorizontalWritingMode()) 471 if (!style()->isHorizontalWritingMode())
418 markerRect = markerRect.transposedRect(); 472 markerRect = markerRect.transposedRect();
419 LayoutBox* o = m_marker; 473 LayoutBox* o = marker;
420 bool propagateVisualOverflow = true; 474 bool propagateVisualOverflow = true;
421 bool propagateLayoutOverflow = true; 475 bool propagateLayoutOverflow = true;
422 do { 476 do {
423 o = o->parentBox(); 477 o = o->parentBox();
424 if (o->isLayoutBlock()) { 478 if (o->isLayoutBlock()) {
425 if (propagateVisualOverflow) 479 if (propagateVisualOverflow)
426 toLayoutBlock(o)->addContentsVisualOverflow(markerRect); 480 toLayoutBlock(o)->addContentsVisualOverflow(markerRect);
427 if (propagateLayoutOverflow) 481 if (propagateLayoutOverflow)
428 toLayoutBlock(o)->addLayoutOverflow(markerRect); 482 toLayoutBlock(o)->addLayoutOverflow(markerRect);
429 } 483 }
(...skipping 12 matching lines...) Expand all
442 void LayoutListItem::paint(const PaintInfo& paintInfo, const LayoutPoint& paintO ffset) 496 void LayoutListItem::paint(const PaintInfo& paintInfo, const LayoutPoint& paintO ffset)
443 { 497 {
444 if (!logicalHeight() && hasOverflowClip()) 498 if (!logicalHeight() && hasOverflowClip())
445 return; 499 return;
446 500
447 LayoutBlockFlow::paint(paintInfo, paintOffset); 501 LayoutBlockFlow::paint(paintInfo, paintOffset);
448 } 502 }
449 503
450 const String& LayoutListItem::markerText() const 504 const String& LayoutListItem::markerText() const
451 { 505 {
452 if (m_marker) 506 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
507 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER)) {
508 if (element->layoutObject()) {
509 ASSERT(element->layoutObject()->isListMarker());
510 return toLayoutListMarker(element->layoutObject())->text();
511 }
512 }
513 } else if (m_marker) {
453 return m_marker->text(); 514 return m_marker->text();
515 }
454 return nullAtom.string(); 516 return nullAtom.string();
455 } 517 }
456 518
457 void LayoutListItem::explicitValueChanged() 519 void LayoutListItem::explicitValueChanged()
458 { 520 {
459 if (m_marker) 521 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
522 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER))
523 element->layoutObject()->setNeedsLayoutAndPrefWidthsRecalcAndFullPai ntInvalidation(LayoutInvalidationReason::ListValueChange);
524 } else if (m_marker) {
460 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(Layo utInvalidationReason::ListValueChange); 525 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(Layo utInvalidationReason::ListValueChange);
526 }
527
461 Node* listNode = enclosingList(this); 528 Node* listNode = enclosingList(this);
462 for (LayoutListItem* item = this; item; item = nextListItem(listNode, item)) 529 for (LayoutListItem* item = this; item; item = nextListItem(listNode, item))
463 item->updateValue(); 530 item->updateValue();
464 } 531 }
465 532
466 void LayoutListItem::setExplicitValue(int value) 533 void LayoutListItem::setExplicitValue(int value)
467 { 534 {
468 ASSERT(node()); 535 ASSERT(node());
469 536
470 if (m_hasExplicitValue && m_explicitValue == value) 537 if (m_hasExplicitValue && m_explicitValue == value)
(...skipping 11 matching lines...) Expand all
482 if (!m_hasExplicitValue) 549 if (!m_hasExplicitValue)
483 return; 550 return;
484 m_hasExplicitValue = false; 551 m_hasExplicitValue = false;
485 m_isValueUpToDate = false; 552 m_isValueUpToDate = false;
486 explicitValueChanged(); 553 explicitValueChanged();
487 } 554 }
488 555
489 void LayoutListItem::setNotInList(bool notInList) 556 void LayoutListItem::setNotInList(bool notInList)
490 { 557 {
491 m_notInList = notInList; 558 m_notInList = notInList;
492 if (m_marker) 559 if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
560 if (PseudoElement* element = toElement(node())->pseudoElement(MARKER)) {
561 ASSERT(element->layoutObject());
562 ASSERT(element->layoutObject()->isListMarker());
563 toLayoutListMarker(element->layoutObject())->updateMarginsAndContent ();
564 }
565 } else if (m_marker) {
493 updateMarkerLocation(); 566 updateMarkerLocation();
567 }
494 } 568 }
495 569
496 static LayoutListItem* previousOrNextItem(bool isListReversed, Node* list, Layou tListItem* item) 570 static LayoutListItem* previousOrNextItem(bool isListReversed, Node* list, Layou tListItem* item)
497 { 571 {
498 return isListReversed ? previousListItem(list, item) : nextListItem(list, it em); 572 return isListReversed ? previousListItem(list, item) : nextListItem(list, it em);
499 } 573 }
500 574
501 void LayoutListItem::updateListMarkerNumbers() 575 void LayoutListItem::updateListMarkerNumbers()
502 { 576 {
503 // If distribution recalc is needed, updateListMarkerNumber will be re-invok ed 577 // 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. 602 // assume that all the following ones have too.
529 // This gives us the opportunity to stop here and avoid 603 // This gives us the opportunity to stop here and avoid
530 // marking the same nodes again. 604 // marking the same nodes again.
531 break; 605 break;
532 } 606 }
533 item->updateValue(); 607 item->updateValue();
534 } 608 }
535 } 609 }
536 610
537 } // namespace blink 611 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698