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

Unified Diff: Source/core/dom/MarkerPseudoElement.cpp

Issue 778003003: List marker pseudo elements. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698