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. |
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 "core/layout/LayoutListItem.h" | 24 #include "core/layout/LayoutListItem.h" |
25 | 25 |
26 #include "core/HTMLNames.h" | |
27 #include "core/dom/shadow/FlatTreeTraversal.h" | 26 #include "core/dom/shadow/FlatTreeTraversal.h" |
28 #include "core/html/HTMLOListElement.h" | 27 #include "core/html/HTMLOListElement.h" |
29 #include "core/layout/LayoutListMarker.h" | 28 #include "core/layout/LayoutListMarker.h" |
30 #include "core/paint/ListItemPainter.h" | 29 #include "core/paint/ListItemPainter.h" |
31 #include "wtf/StdLibExtras.h" | 30 #include "wtf/StdLibExtras.h" |
32 #include "wtf/text/StringBuilder.h" | 31 #include "wtf/text/StringBuilder.h" |
33 | 32 |
34 namespace blink { | 33 namespace blink { |
35 | 34 |
36 using namespace HTMLNames; | 35 namespace { |
36 LayoutObject* getParentOfFirstLineBox(LayoutBlockFlow* curr, LayoutListMarker* m arker) | |
eae
2016/09/09 08:55:56
Why not make it a static inline instead?
Gleb Lanbin
2016/09/09 16:06:53
'inline' is recommended for function that are smal
| |
37 { | |
38 LayoutObject* firstChild = curr->firstChild(); | |
39 if (!firstChild) | |
40 return nullptr; | |
41 | |
42 bool inQuirksMode = curr->document().inQuirksMode(); | |
43 for (LayoutObject* currChild = firstChild; currChild; currChild = currChild- >nextSibling()) { | |
44 if (currChild == marker) | |
45 continue; | |
46 | |
47 if (currChild->isInline() && (!currChild->isLayoutInline() || curr->gene ratesLineBoxesForInlineChild(currChild))) | |
48 return curr; | |
49 | |
50 if (currChild->isFloating() || currChild->isOutOfFlowPositioned()) | |
51 continue; | |
52 | |
53 if (!currChild->isLayoutBlockFlow() || (currChild->isBox() && toLayoutBo x(currChild)->isWritingModeRoot())) | |
54 break; | |
55 | |
56 if (curr->isListItem() && inQuirksMode && currChild->node() | |
57 && (isHTMLUListElement(*currChild->node()) || isHTMLOListElement(*cu rrChild->node()))) | |
58 break; | |
59 | |
60 LayoutObject* lineBox = getParentOfFirstLineBox(toLayoutBlockFlow(currCh ild), marker); | |
61 if (lineBox) | |
62 return lineBox; | |
63 } | |
64 | |
65 return nullptr; | |
66 } | |
67 } // namespace | |
37 | 68 |
38 LayoutListItem::LayoutListItem(Element* element) | 69 LayoutListItem::LayoutListItem(Element* element) |
39 : LayoutBlockFlow(element) | 70 : LayoutBlockFlow(element) |
40 , m_marker(nullptr) | 71 , m_marker(nullptr) |
41 , m_hasExplicitValue(false) | 72 , m_hasExplicitValue(false) |
42 , m_isValueUpToDate(false) | 73 , m_isValueUpToDate(false) |
43 , m_notInList(false) | 74 , m_notInList(false) |
44 { | 75 { |
45 setInline(false); | 76 setInline(false); |
46 | 77 |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 { | 269 { |
239 m_value = calcValue(); | 270 m_value = calcValue(); |
240 m_isValueUpToDate = true; | 271 m_isValueUpToDate = true; |
241 } | 272 } |
242 | 273 |
243 bool LayoutListItem::isEmpty() const | 274 bool LayoutListItem::isEmpty() const |
244 { | 275 { |
245 return lastChild() == m_marker; | 276 return lastChild() == m_marker; |
246 } | 277 } |
247 | 278 |
248 static LayoutObject* getParentOfFirstLineBox(LayoutBlockFlow* curr, LayoutObject * marker) | |
249 { | |
250 LayoutObject* firstChild = curr->firstChild(); | |
251 if (!firstChild) | |
252 return nullptr; | |
253 | |
254 bool inQuirksMode = curr->document().inQuirksMode(); | |
255 for (LayoutObject* currChild = firstChild; currChild; currChild = currChild- >nextSibling()) { | |
256 if (currChild == marker) | |
257 continue; | |
258 | |
259 if (currChild->isInline() && (!currChild->isLayoutInline() || curr->gene ratesLineBoxesForInlineChild(currChild))) | |
260 return curr; | |
261 | |
262 if (currChild->isFloating() || currChild->isOutOfFlowPositioned()) | |
263 continue; | |
264 | |
265 if (!currChild->isLayoutBlockFlow() || (currChild->isBox() && toLayoutBo x(currChild)->isWritingModeRoot())) | |
266 break; | |
267 | |
268 if (curr->isListItem() && inQuirksMode && currChild->node() | |
269 && (isHTMLUListElement(*currChild->node()) || isHTMLOListElement(*cu rrChild->node()))) | |
270 break; | |
271 | |
272 LayoutObject* lineBox = getParentOfFirstLineBox(toLayoutBlockFlow(currCh ild), marker); | |
273 if (lineBox) | |
274 return lineBox; | |
275 } | |
276 | |
277 return nullptr; | |
278 } | |
279 | |
280 void LayoutListItem::updateValue() | 279 void LayoutListItem::updateValue() |
281 { | 280 { |
282 if (!m_hasExplicitValue) { | 281 if (!m_hasExplicitValue) { |
283 m_isValueUpToDate = false; | 282 m_isValueUpToDate = false; |
284 if (m_marker) | 283 if (m_marker) |
285 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( LayoutInvalidationReason::ListValueChange); | 284 m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( LayoutInvalidationReason::ListValueChange); |
286 } | 285 } |
287 } | 286 } |
288 | 287 |
289 static LayoutObject* firstNonMarkerChild(LayoutObject* parent) | 288 static LayoutObject* firstNonMarkerChild(LayoutObject* parent) |
290 { | 289 { |
291 LayoutObject* result = parent->slowFirstChild(); | 290 LayoutObject* result = parent->slowFirstChild(); |
292 while (result && result->isListMarker()) | 291 while (result && result->isListMarker()) |
293 result = result->nextSibling(); | 292 result = result->nextSibling(); |
294 return result; | 293 return result; |
295 } | 294 } |
296 | 295 |
297 bool LayoutListItem::updateMarkerLocation() | 296 bool LayoutListItem::updateMarkerLocation() |
298 { | 297 { |
299 ASSERT(m_marker); | 298 ASSERT(m_marker); |
300 | 299 |
301 LayoutObject* markerParent = m_marker->parent(); | 300 LayoutObject* markerParent = m_marker->parent(); |
302 LayoutObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker); | 301 // list-style-position:inside makes the ::marker pseudo an ordinary position :static element that should be attached to LayoutListItem block. |
302 LayoutObject* lineBoxParent = m_marker->isInside() ? this : getParentOfFirst LineBox(this, m_marker); | |
303 if (!lineBoxParent) { | 303 if (!lineBoxParent) { |
304 // If the marker is currently contained inside an anonymous box, then we | 304 // If the marker is currently contained inside an anonymous box, then we |
305 // are the only item in that anonymous box (since no line box parent was | 305 // are the only item in that anonymous box (since no line box parent was |
306 // found). It's ok to just leave the marker where it is in this case. | 306 // found). It's ok to just leave the marker where it is in this case. |
307 if (markerParent && markerParent->isAnonymousBlock()) | 307 if (markerParent && markerParent->isAnonymousBlock()) |
308 lineBoxParent = markerParent; | 308 lineBoxParent = markerParent; |
309 else | 309 else |
310 lineBoxParent = this; | 310 lineBoxParent = this; |
311 } | 311 } |
312 | 312 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
508 // assume that all the following ones have too. | 508 // assume that all the following ones have too. |
509 // This gives us the opportunity to stop here and avoid | 509 // This gives us the opportunity to stop here and avoid |
510 // marking the same nodes again. | 510 // marking the same nodes again. |
511 break; | 511 break; |
512 } | 512 } |
513 item->updateValue(); | 513 item->updateValue(); |
514 } | 514 } |
515 } | 515 } |
516 | 516 |
517 } // namespace blink | 517 } // namespace blink |
OLD | NEW |