Chromium Code Reviews| Index: Source/core/dom/MarkerPseudoElement.cpp |
| diff --git a/Source/core/dom/MarkerPseudoElement.cpp b/Source/core/dom/MarkerPseudoElement.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..70654caa1907290a85ec86f6b5d2c8b7102b7b06 |
| --- /dev/null |
| +++ b/Source/core/dom/MarkerPseudoElement.cpp |
| @@ -0,0 +1,118 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "config.h" |
| +#include "core/dom/MarkerPseudoElement.h" |
| + |
| +#include "core/rendering/RenderBlockFlow.h" |
| +#include "core/rendering/RenderListItem.h" |
| +#include "core/rendering/RenderListMarker.h" |
| + |
| +namespace blink { |
| + |
| +MarkerPseudoElement::MarkerPseudoElement(Element* parent) |
| + : PseudoElement(parent, MARKER) |
| +{ |
| +} |
| + |
| +MarkerPseudoElement::~MarkerPseudoElement() |
| +{ |
| +} |
| + |
| +RenderObject* MarkerPseudoElement::getParentOfFirstLineBox(RenderBlockFlow* curr, const RenderObject* marker) |
| +{ |
| + RenderObject* firstChild = curr->firstChild(); |
| + if (!firstChild) |
| + return nullptr; |
| + |
| + bool inQuirksMode = curr->document().inQuirksMode(); |
| + for (RenderObject* currChild = firstChild; currChild; currChild = currChild->nextSibling()) { |
| + if (currChild == marker) |
| + continue; |
| + |
| + if (currChild->isInline() && (!currChild->isRenderInline() || curr->generatesLineBoxesForInlineChild(currChild))) |
| + return curr; |
| + |
| + if (currChild->isFloating() || currChild->isOutOfFlowPositioned()) |
| + continue; |
| + |
| + if (!currChild->isRenderBlockFlow() || (currChild->isBox() && toRenderBox(currChild)->isWritingModeRoot())) |
| + break; |
| + |
| + if (curr->isListItem() && inQuirksMode && currChild->node() && |
| + (isHTMLUListElement(*currChild->node()) || isHTMLOListElement(*currChild->node()))) |
| + break; |
| + |
| + if (RenderObject* lineBox = getParentOfFirstLineBox(toRenderBlockFlow(currChild), marker)) |
| + return lineBox; |
| + } |
| + |
| + return nullptr; |
| +} |
|
Julien - ping for review
2014/12/05 19:44:03
Does that code really still apply with a pseudo?
dsinclair
2015/01/23 20:46:36
Yes, we still have to put the renderer somewhere.
|
| + |
| +RenderObject* MarkerPseudoElement::firstNonMarkerChild(RenderObject* parent) |
| +{ |
| + RenderObject* result = parent->slowFirstChild(); |
| + while (result && result->isListMarker()) |
| + result = result->nextSibling(); |
| + return result; |
| +} |
| + |
| +RenderObject* MarkerPseudoElement::createRenderer(RenderStyle* style) |
| +{ |
| + ASSERT(parentElement()->renderer()); |
| + RenderListMarker* marker = RenderListMarker::createAnonymous(toRenderListItem(parentElement()->renderer())); |
| + marker->setStyle(style); |
| + return marker; |
| +} |
| + |
| +void MarkerPseudoElement::attachListMarkerRenderer() |
| +{ |
| + RenderListItem* parentRenderer = toRenderListItem(parentElement()->renderer()); |
| + ASSERT(parentRenderer); |
| + ASSERT(parentRenderer->isListItem()); |
|
Julien - ping for review
2014/12/05 19:44:03
*cough, cough* toRenderListItem(parentRenderer) *c
dsinclair
2015/01/23 20:46:36
Done.
|
| + |
| + ASSERT(renderer()); |
|
Julien - ping for review
2014/12/05 19:44:04
Probably bad assumption no? How about changing dis
dsinclair
2015/01/23 20:46:36
I believe this is safe, if we have a pseudo elemen
|
| + RenderListMarker* marker = toRenderListMarker(renderer()); |
| + |
| + RenderObject* markerParent = marker->parent(); |
| + ASSERT(markerParent); |
|
dsinclair
2015/01/23 20:46:36
This one, on the other hand, is a bad assumption.
|
| + |
| + RenderObject* insertionRenderer = MarkerPseudoElement::getParentOfFirstLineBox(parentRenderer, marker); |
| + |
| + // We didn't find any line boxes so make the insertion point the LI renderer. |
| + if (!insertionRenderer) |
| + insertionRenderer = parentRenderer; |
| + ASSERT(insertionRenderer); |
| + |
| + // Check if we're already inserted into the right parent as the first child. |
| + if (marker == markerParent->slowFirstChild() && |
| + (markerParent == insertionRenderer || markerParent == insertionRenderer->slowFirstChild())) |
| + return; |
| + |
| + marker->remove(); |
| + insertionRenderer->addChild(marker, MarkerPseudoElement::firstNonMarkerChild(insertionRenderer)); |
| + marker->updateMarginsAndContent(); |
| + |
| + // If markerParent is an anonymous block with no children, destroy it. |
| + if (markerParent->isAnonymousBlock() && !toRenderBlock(markerParent)->firstChild() && !toRenderBlock(markerParent)->continuation()) |
| + markerParent->destroy(); |
| + |
| + if (marker->isInside()) |
| + parentRenderer->containingBlock()->updateLogicalWidth(); |
| +} |
| + |
| +void MarkerPseudoElement::attach(const AttachContext& context) |
| +{ |
| + PseudoElement::attach(context); |
| + ASSERT(renderer()); |
|
Julien - ping for review
2014/12/05 19:44:03
Same comment, is this assumption correct?
dsinclair
2015/01/23 20:46:36
As above.
|
| + toRenderListMarker(renderer())->listItemStyleDidChange(); |
| +} |
| + |
| +void MarkerPseudoElement::didRecalcStyle(StyleRecalcChange) |
| +{ |
| + attachListMarkerRenderer(); |
| +} |
| + |
| +} // namespace blink |