OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 #include "core/dom/MarkerPseudoElement.h" | |
7 | |
8 #include "core/layout/LayoutBlockFlow.h" | |
9 #include "core/layout/LayoutListItem.h" | |
10 #include "core/layout/LayoutListMarker.h" | |
11 | |
12 namespace blink { | |
13 | |
14 MarkerPseudoElement::MarkerPseudoElement(Element* parent) | |
15 : PseudoElement(parent, MARKER) | |
16 { | |
17 } | |
18 | |
19 MarkerPseudoElement::~MarkerPseudoElement() | |
20 { | |
21 } | |
22 | |
23 LayoutObject* MarkerPseudoElement::parentOfFirstLineBox(LayoutBlockFlow* curr, c onst LayoutObject* marker) | |
24 { | |
25 LayoutObject* firstChild = curr->firstChild(); | |
26 if (!firstChild) | |
27 return nullptr; | |
28 | |
29 bool inQuirksMode = curr->document().inQuirksMode(); | |
30 for (LayoutObject* currChild = firstChild; currChild; currChild = currChild- >nextSibling()) { | |
31 if (currChild == marker) | |
32 continue; | |
33 | |
34 if (currChild->isInline() && (!currChild->isLayoutInline() || curr->gene ratesLineBoxesForInlineChild(currChild))) | |
35 return curr; | |
36 | |
37 if (currChild->isFloating() || currChild->isOutOfFlowPositioned()) | |
38 continue; | |
39 | |
40 if (!currChild->isLayoutBlockFlow() || (currChild->isBox() && toLayoutBo x(currChild)->isWritingModeRoot())) | |
41 break; | |
42 | |
43 if (curr->isListItem() && inQuirksMode && currChild->node() | |
44 && (isHTMLUListElement(*currChild->node()) || isHTMLOListElement(*cu rrChild->node()))) | |
45 break; | |
46 | |
47 if (LayoutObject* lineBox = parentOfFirstLineBox(toLayoutBlockFlow(currC hild), marker)) | |
48 return lineBox; | |
49 } | |
50 | |
51 return nullptr; | |
52 } | |
53 | |
54 PassRefPtr<ComputedStyle> MarkerPseudoElement::customStyleForLayoutObject() | |
55 { | |
56 if (!layoutObject()) | |
esprehn
2015/04/22 07:45:45
This isn't right, you should never look at the lay
dsinclair
2015/04/22 20:00:38
Removed customStyleForLayoutObjects and did calls
| |
57 return nullptr; | |
58 | |
59 LayoutObject* parent = layoutObject()->parent(); | |
esprehn
2015/04/22 07:45:45
You need to call LayoutTreeBuilderTraversal::paren
dsinclair
2015/04/22 20:00:38
Removed.
| |
60 if (!parent) | |
61 return nullptr; | |
62 | |
63 return styleForListMarkerLayoutObject(*parent, layoutObject()->style()); | |
64 } | |
65 | |
66 PassRefPtr<ComputedStyle> MarkerPseudoElement::styleForListMarkerLayoutObject(La youtObject& parent, const ComputedStyle* style) | |
esprehn
2015/04/22 07:45:45
styleForListMarker(...) no need for LayoutObject i
dsinclair
2015/04/22 20:00:38
Done.
| |
67 { | |
68 RefPtr<ComputedStyle> newStyle = ComputedStyle::create(); | |
69 | |
70 // The marker always inherits from the list item, regardless of where it mig ht end | |
71 // up (e.g., in some deeply nested line box). See CSS3 spec. | |
72 newStyle->inheritFrom(*parent.style()); | |
73 if (style) { | |
74 // Reuse the current margins. Otherwise resetting the margins to initial values | |
75 // would trigger unnecessary layout. | |
76 newStyle->setMarginStart(style->marginStart()); | |
77 newStyle->setMarginEnd(style->marginRight()); | |
esprehn
2015/04/22 07:45:45
This code should just be inlined in the above meth
dsinclair
2015/04/22 20:00:38
It can be in the future when we remove the old cod
| |
78 } | |
79 return newStyle; | |
80 } | |
81 | |
82 LayoutObject* MarkerPseudoElement::firstNonMarkerChild(LayoutObject* parent) | |
83 { | |
84 LayoutObject* result = parent->slowFirstChild(); | |
85 while (result && result->isListMarker()) | |
86 result = result->nextSibling(); | |
87 return result; | |
88 } | |
89 | |
90 LayoutObject* MarkerPseudoElement::createLayoutObject(const ComputedStyle& style ) | |
91 { | |
92 ASSERT(parentElement()->layoutObject()); | |
93 LayoutListMarker* marker = new LayoutListMarker(this, toLayoutListItem(paren tElement()->layoutObject())); | |
94 marker->setStyle(ComputedStyle::clone(style)); | |
esprehn
2015/04/22 07:45:45
Don't clone the style, you never need to do that i
dsinclair
2015/04/22 20:00:38
Done.
| |
95 return marker; | |
96 } | |
97 | |
98 void MarkerPseudoElement::attachListMarkerLayoutObject() | |
99 { | |
100 LayoutListItem* parentLayoutObject = toLayoutListItem(parentElement()->layou tObject()); | |
101 ASSERT(parentLayoutObject); | |
102 ASSERT(layoutObject()); | |
103 | |
104 LayoutListMarker* marker = toLayoutListMarker(layoutObject()); | |
105 LayoutObject* markerParent = marker->parent(); | |
106 | |
107 LayoutObject* insertionLayoutObject = MarkerPseudoElement::parentOfFirstLine Box(parentLayoutObject, marker); | |
108 | |
109 // We didn't find any line boxes so make the insertion point the LI layoutOb ject. | |
110 if (!insertionLayoutObject) | |
111 insertionLayoutObject = parentLayoutObject; | |
112 ASSERT(insertionLayoutObject); | |
113 | |
114 // Check if we're already inserted into the right parent as the first child. | |
115 if (markerParent && marker == markerParent->slowFirstChild() | |
116 && (markerParent == insertionLayoutObject || markerParent == insertionLa youtObject->slowFirstChild())) | |
117 return; | |
118 | |
119 marker->remove(); | |
120 insertionLayoutObject->addChild(marker, MarkerPseudoElement::firstNonMarkerC hild(insertionLayoutObject)); | |
121 marker->updateMarginsAndContent(); | |
esprehn
2015/04/22 07:45:45
Layout calls this for isImage(), make it call it e
dsinclair
2015/04/22 20:00:38
That will mean we'll do it on every layout, where
| |
122 | |
123 // If markerParent is an anonymous block with no children, destroy it. | |
124 if (markerParent && markerParent->isAnonymousBlock() && !toLayoutBlock(marke rParent)->firstChild() && !toLayoutBlock(markerParent)->continuation()) | |
125 markerParent->destroy(); | |
126 | |
127 if (marker->isInside()) | |
128 parentLayoutObject->containingBlock()->updateLogicalWidth(); | |
esprehn
2015/04/22 07:45:45
You can't update logical widths inside style recal
dsinclair
2015/04/22 20:00:38
Done.
| |
129 } | |
130 | |
131 void MarkerPseudoElement::attach(const AttachContext& context) | |
132 { | |
133 PseudoElement::attach(context); | |
134 ASSERT(layoutObject()); | |
135 | |
136 LayoutListMarker* marker = toLayoutListMarker(layoutObject()); | |
137 | |
138 RefPtr<ComputedStyle> newStyle = MarkerPseudoElement::styleForListMarkerLayo utObject(*(marker->mutableListItem()), marker->style()); | |
139 marker->setStyle(newStyle.release()); | |
esprehn
2015/04/22 07:45:45
::attach went through the customStyleForLayoutObje
dsinclair
2015/04/22 20:00:38
Style is set here only now.
| |
140 | |
141 attachListMarkerLayoutObject(); | |
142 } | |
143 | |
144 void MarkerPseudoElement::didRecalcStyle(StyleRecalcChange) | |
145 { | |
146 attachListMarkerLayoutObject(); | |
147 } | |
148 | |
149 } // namespace blink | |
OLD | NEW |