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

Side by Side Diff: Source/core/dom/MarkerPseudoElement.cpp

Issue 778003003: List marker pseudo elements. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 10 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
(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/rendering/RenderBlockFlow.h"
9 #include "core/rendering/RenderListItem.h"
10 #include "core/rendering/RenderListMarker.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 RenderObject* MarkerPseudoElement::getParentOfFirstLineBox(RenderBlockFlow* curr , const RenderObject* marker)
24 {
25 RenderObject* firstChild = curr->firstChild();
26 if (!firstChild)
27 return nullptr;
28
29 bool inQuirksMode = curr->document().inQuirksMode();
30 for (RenderObject* currChild = firstChild; currChild; currChild = currChild- >nextSibling()) {
31 if (currChild == marker)
32 continue;
33
34 if (currChild->isInline() && (!currChild->isRenderInline() || curr->gene ratesLineBoxesForInlineChild(currChild)))
35 return curr;
36
37 if (currChild->isFloating() || currChild->isOutOfFlowPositioned())
38 continue;
39
40 if (!currChild->isRenderBlockFlow() || (currChild->isBox() && toRenderBo 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 (RenderObject* lineBox = getParentOfFirstLineBox(toRenderBlockFlow(cu rrChild), marker))
48 return lineBox;
49 }
50
51 return nullptr;
52 }
53
54 PassRefPtr<RenderStyle> MarkerPseudoElement::customStyleForRenderer()
Julien - ping for review 2015/02/04 01:56:33 Is this function ever called?
dsinclair 2015/02/04 04:41:33 Yes. This is an override of a method on Element. I
55 {
56 if (!renderer())
57 return nullptr;
58
59 RenderObject* parent = renderer()->parent();
60 if (!parent)
61 return nullptr;
62
63 return styleForListMarkerRenderer(*parent, renderer()->style());
64 }
65
66 PassRefPtr<RenderStyle> MarkerPseudoElement::styleForListMarkerRenderer(RenderOb ject& parent, RenderStyle* style)
67 {
68 RefPtr<RenderStyle> newStyle = RenderStyle::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());
78 }
Julien - ping for review 2015/02/04 01:56:34 Couldn't we just have a CSS rule to handle that?
dsinclair 2015/02/04 04:41:33 A CSS rule to handle what, the resetting of the ma
79 return newStyle;
80 }
81
82 RenderObject* MarkerPseudoElement::firstNonMarkerChild(RenderObject* parent)
83 {
84 RenderObject* result = parent->slowFirstChild();
85 while (result && result->isListMarker())
86 result = result->nextSibling();
87 return result;
88 }
89
90 void MarkerPseudoElement::removeListMarker()
91 {
92 setRenderer(nullptr);
93 }
94
95
96 RenderObject* MarkerPseudoElement::createRenderer(RenderStyle* style)
97 {
98 ASSERT(parentElement()->renderer());
99 RenderListMarker* marker = new RenderListMarker(this, toRenderListItem(paren tElement()->renderer()));
100 marker->setStyle(style);
101 return marker;
102 }
103
104 void MarkerPseudoElement::attachListMarkerRenderer()
105 {
106 RenderListItem* parentRenderer = toRenderListItem(parentElement()->renderer( ));
107 ASSERT(parentRenderer);
108 ASSERT(renderer());
109
110 RenderListMarker* marker = toRenderListMarker(renderer());
111 RenderObject* markerParent = marker->parent();
112
113 RenderObject* insertionRenderer = MarkerPseudoElement::getParentOfFirstLineB ox(parentRenderer, marker);
114
115 // We didn't find any line boxes so make the insertion point the LI renderer .
116 if (!insertionRenderer)
117 insertionRenderer = parentRenderer;
118 ASSERT(insertionRenderer);
119
120 // Check if we're already inserted into the right parent as the first child.
121 if (markerParent && marker == markerParent->slowFirstChild()
122 && (markerParent == insertionRenderer || markerParent == insertionRender er->slowFirstChild()))
123 return;
124
125 marker->remove();
126 insertionRenderer->addChild(marker, MarkerPseudoElement::firstNonMarkerChild (insertionRenderer));
127 marker->updateMarginsAndContent();
128
129 // If markerParent is an anonymous block with no children, destroy it.
130 if (markerParent && markerParent->isAnonymousBlock() && !toRenderBlock(marke rParent)->firstChild() && !toRenderBlock(markerParent)->continuation())
131 markerParent->destroy();
132
133 if (marker->isInside())
134 parentRenderer->containingBlock()->updateLogicalWidth();
135 }
136
137 void MarkerPseudoElement::attach(const AttachContext& context)
138 {
139 PseudoElement::attach(context);
140 ASSERT(renderer());
141 toRenderListMarker(renderer())->listItemStyleDidChange();
142 }
143
144 void MarkerPseudoElement::didRecalcStyle(StyleRecalcChange)
145 {
146 attachListMarkerRenderer();
147 }
148
149 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698