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

Unified Diff: Source/core/rendering/RenderListItem.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/rendering/RenderListItem.cpp
diff --git a/Source/core/rendering/RenderListItem.cpp b/Source/core/rendering/RenderListItem.cpp
index 014cec2543015fe28950c21179c2986cfa8d5f36..0d81c20f004bc3d4be7f842cf656980397ed12f2 100644
--- a/Source/core/rendering/RenderListItem.cpp
+++ b/Source/core/rendering/RenderListItem.cpp
@@ -26,6 +26,7 @@
#include "core/HTMLNames.h"
#include "core/dom/NodeRenderingTraversal.h"
+#include "core/dom/MarkerPseudoElement.h"
#include "core/html/HTMLOListElement.h"
#include "core/rendering/RenderListMarker.h"
#include "core/rendering/RenderView.h"
@@ -57,14 +58,16 @@ void RenderListItem::styleDidChange(StyleDifference diff, const RenderStyle* old
{
RenderBlockFlow::styleDidChange(diff, oldStyle);
- if (style()->listStyleType() != NoneListStyle
- || (style()->listStyleImage() && !style()->listStyleImage()->errorOccurred())) {
- if (!m_marker)
- m_marker = RenderListMarker::createAnonymous(this);
- m_marker->listItemStyleDidChange();
- } else if (m_marker) {
- m_marker->destroy();
- m_marker = nullptr;
+ if (!RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
Julien - ping for review 2014/12/05 19:44:04 We prefer early return.
dsinclair 2015/01/23 20:46:36 Done.
+ if (style()->listStyleType() != NoneListStyle
+ || (style()->listStyleImage() && !style()->listStyleImage()->errorOccurred())) {
+ if (!m_marker)
+ m_marker = RenderListMarker::createAnonymous(this);
+ m_marker->listItemStyleDidChange();
+ } else if (m_marker) {
+ m_marker->destroy();
+ m_marker = nullptr;
+ }
}
}
@@ -74,6 +77,7 @@ void RenderListItem::willBeDestroyed()
m_marker->destroy();
m_marker = nullptr;
}
+
RenderBlockFlow::willBeDestroyed();
}
@@ -219,60 +223,27 @@ void RenderListItem::updateValueNow() const
bool RenderListItem::isEmpty() const
{
+ if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled())
+ return isEmpty();
Julien - ping for review 2014/12/05 19:44:04 Really nice infinite loop?
dsinclair 2015/01/23 20:46:36 Done.
return lastChild() == m_marker;
}
-static RenderObject* getParentOfFirstLineBox(RenderBlockFlow* curr, RenderObject* marker)
-{
- RenderObject* firstChild = curr->firstChild();
- if (!firstChild)
- return 0;
-
- 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;
-
- RenderObject* lineBox = getParentOfFirstLineBox(toRenderBlockFlow(currChild), marker);
- if (lineBox)
- return lineBox;
- }
-
- return 0;
-}
-
void RenderListItem::updateValue()
{
if (!m_hasExplicitValue) {
m_isValueUpToDate = false;
- if (m_marker)
+ if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
+ if (PseudoElement* element = toElement(node())->pseudoElement(MARKER))
+ element->renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ } else if (m_marker) {
m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ }
}
}
-static RenderObject* firstNonMarkerChild(RenderObject* parent)
-{
- RenderObject* result = parent->slowFirstChild();
- while (result && result->isListMarker())
- result = result->nextSibling();
- return result;
-}
-
void RenderListItem::updateMarkerLocationAndInvalidateWidth()
{
+ ASSERT(!RuntimeEnabledFeatures::listMarkerPseudoElementEnabled());
ASSERT(m_marker);
// FIXME: We should not modify the structure of the render tree
@@ -288,9 +259,11 @@ void RenderListItem::updateMarkerLocationAndInvalidateWidth()
bool RenderListItem::updateMarkerLocation()
{
+ ASSERT(!RuntimeEnabledFeatures::listMarkerPseudoElementEnabled());
ASSERT(m_marker);
+
RenderObject* markerParent = m_marker->parent();
- RenderObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker);
+ RenderObject* lineBoxParent = MarkerPseudoElement::getParentOfFirstLineBox(this, m_marker);
if (!lineBoxParent) {
// If the marker is currently contained inside an anonymous box, then we
// are the only item in that anonymous box (since no line box parent was
@@ -303,7 +276,7 @@ bool RenderListItem::updateMarkerLocation()
if (markerParent != lineBoxParent) {
m_marker->remove();
- lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent));
+ lineBoxParent->addChild(m_marker, MarkerPseudoElement::firstNonMarkerChild(lineBoxParent));
m_marker->updateMarginsAndContent();
// If markerParent is an anonymous block with no children, destroy it.
if (markerParent && markerParent->isAnonymousBlock() && !toRenderBlock(markerParent)->firstChild() && !toRenderBlock(markerParent)->continuation())
@@ -318,7 +291,23 @@ void RenderListItem::layout()
{
ASSERT(needsLayout());
- if (m_marker) {
+ if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
+ if (PseudoElement* element = toElement(node())->pseudoElement(MARKER)) {
+ ASSERT(element->renderer()->isListMarker());
+ RenderListMarker* marker = toRenderListMarker(element->renderer());
+
+ // The marker must be autosized before calling
+ // updateMarkerLocationAndInvalidateWidth. It cannot be done in the
+ // parent's beginLayout because it is not yet in the render tree.
+ if (TextAutosizer* textAutosizer = document().textAutosizer())
+ textAutosizer->inflateListItem(this, marker);
+
+ marker->updateMarginsAndContent();
+ if (marker->isInside())
+ containingBlock()->updateLogicalWidth();
+ }
+
+ } else if (m_marker) {
// The marker must be autosized before calling
// updateMarkerLocationAndInvalidateWidth. It cannot be done in the
// parent's beginLayout because it is not yet in the render tree.
@@ -334,23 +323,32 @@ void RenderListItem::layout()
void RenderListItem::addOverflowFromChildren()
{
RenderBlockFlow::addOverflowFromChildren();
- positionListMarker();
+
+ if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
+ MarkerPseudoElement* markerElement = toMarkerPseudoElement(toElement(node())->pseudoElement(MARKER));
+ if (markerElement && markerElement->renderer()) {
+ ASSERT(markerElement->renderer()->isListMarker());
+ positionListMarker(toRenderListMarker(markerElement->renderer()));
+ }
+ } else {
+ positionListMarker(m_marker);
+ }
}
-void RenderListItem::positionListMarker()
+void RenderListItem::positionListMarker(RenderListMarker* marker)
{
- if (m_marker && m_marker->parent()->isBox() && !m_marker->isInside() && m_marker->inlineBoxWrapper()) {
- LayoutUnit markerOldLogicalLeft = m_marker->logicalLeft();
+ if (marker && marker->parent()->isBox() && !marker->isInside() && marker->inlineBoxWrapper()) {
+ LayoutUnit markerOldLogicalLeft = marker->logicalLeft();
LayoutUnit blockOffset = 0;
LayoutUnit lineOffset = 0;
- for (RenderBox* o = m_marker->parentBox(); o != this; o = o->parentBox()) {
+ for (RenderBox* o = marker->parentBox(); o != this; o = o->parentBox()) {
blockOffset += o->logicalTop();
lineOffset += o->logicalLeft();
}
bool adjustOverflow = false;
LayoutUnit markerLogicalLeft;
- RootInlineBox& root = m_marker->inlineBoxWrapper()->root();
+ RootInlineBox& root = marker->inlineBoxWrapper()->root();
bool hitSelfPaintingLayer = false;
LayoutUnit lineTop = root.lineTop();
@@ -359,9 +357,9 @@ void RenderListItem::positionListMarker()
// FIXME: Need to account for relative positioning in the layout overflow.
if (style()->isLeftToRightDirection()) {
LayoutUnit leftLineOffset = logicalLeftOffsetForLine(blockOffset, logicalLeftOffsetForLine(blockOffset, false), false);
- markerLogicalLeft = leftLineOffset - lineOffset - paddingStart() - borderStart() + m_marker->marginStart();
- m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogicalLeft - markerOldLogicalLeft).toFloat());
- for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
+ markerLogicalLeft = leftLineOffset - lineOffset - paddingStart() - borderStart() + marker->marginStart();
+ marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogicalLeft - markerOldLogicalLeft).toFloat());
+ for (InlineFlowBox* box = marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect(lineTop, lineBottom);
LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect(lineTop, lineBottom);
if (markerLogicalLeft < newLogicalVisualOverflowRect.x() && !hitSelfPaintingLayer) {
@@ -382,18 +380,18 @@ void RenderListItem::positionListMarker()
}
} else {
LayoutUnit rightLineOffset = logicalRightOffsetForLine(blockOffset, logicalRightOffsetForLine(blockOffset, false), false);
- markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + m_marker->marginEnd();
- m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogicalLeft - markerOldLogicalLeft).toFloat());
- for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
+ markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + marker->marginEnd();
+ marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogicalLeft - markerOldLogicalLeft).toFloat());
+ for (InlineFlowBox* box = marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect(lineTop, lineBottom);
LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect(lineTop, lineBottom);
- if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalVisualOverflowRect.maxX() && !hitSelfPaintingLayer) {
- newLogicalVisualOverflowRect.setWidth(markerLogicalLeft + m_marker->logicalWidth() - newLogicalVisualOverflowRect.x());
+ if (markerLogicalLeft + marker->logicalWidth() > newLogicalVisualOverflowRect.maxX() && !hitSelfPaintingLayer) {
+ newLogicalVisualOverflowRect.setWidth(markerLogicalLeft + marker->logicalWidth() - newLogicalVisualOverflowRect.x());
if (box == root)
adjustOverflow = true;
}
- if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalLayoutOverflowRect.maxX()) {
- newLogicalLayoutOverflowRect.setWidth(markerLogicalLeft + m_marker->logicalWidth() - newLogicalLayoutOverflowRect.x());
+ if (markerLogicalLeft + marker->logicalWidth() > newLogicalLayoutOverflowRect.maxX()) {
+ newLogicalLayoutOverflowRect.setWidth(markerLogicalLeft + marker->logicalWidth() - newLogicalLayoutOverflowRect.x());
if (box == root)
adjustOverflow = true;
}
@@ -405,10 +403,10 @@ void RenderListItem::positionListMarker()
}
if (adjustOverflow) {
- LayoutRect markerRect(markerLogicalLeft + lineOffset, blockOffset, m_marker->width(), m_marker->height());
+ LayoutRect markerRect(markerLogicalLeft + lineOffset, blockOffset, marker->width(), marker->height());
if (!style()->isHorizontalWritingMode())
markerRect = markerRect.transposedRect();
- RenderBox* o = m_marker;
+ RenderBox* o = marker;
bool propagateVisualOverflow = true;
bool propagateLayoutOverflow = true;
do {
@@ -441,15 +439,28 @@ void RenderListItem::paint(const PaintInfo& paintInfo, const LayoutPoint& paintO
const String& RenderListItem::markerText() const
{
- if (m_marker)
+ if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
+ if (PseudoElement* element = toElement(node())->pseudoElement(MARKER)) {
+ if (element->renderer()) {
+ ASSERT(element->renderer()->isListMarker());
+ return toRenderListMarker(element->renderer())->text();
+ }
+ }
+ } else if (m_marker) {
return m_marker->text();
+ }
return nullAtom.string();
}
void RenderListItem::explicitValueChanged()
{
- if (m_marker)
+ if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
+ if (PseudoElement* element = toElement(node())->pseudoElement(MARKER))
+ element->renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ } else if (m_marker) {
m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ }
+
Node* listNode = enclosingList(this);
for (RenderListItem* item = this; item; item = nextListItem(listNode, item))
item->updateValue();
@@ -481,8 +492,15 @@ void RenderListItem::clearExplicitValue()
void RenderListItem::setNotInList(bool notInList)
{
m_notInList = notInList;
- if (m_marker)
+ if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) {
+ if (PseudoElement* element = toElement(node())->pseudoElement(MARKER)) {
+ ASSERT(element->renderer());
+ ASSERT(element->renderer()->isListMarker());
+ toRenderListMarker(element->renderer())->updateMarginsAndContent();
+ }
+ } else if (m_marker) {
updateMarkerLocation();
+ }
}
static RenderListItem* previousOrNextItem(bool isListReversed, Node* list, RenderListItem* item)

Powered by Google App Engine
This is Rietveld 408576698