Index: Source/core/rendering/RenderListItem.cpp |
diff --git a/Source/core/rendering/RenderListItem.cpp b/Source/core/rendering/RenderListItem.cpp |
index bf6a93ec95f949b18064f338470f9235e552b0a2..507cc08a6b92d361c5759816cbaa006fc882c602 100644 |
--- a/Source/core/rendering/RenderListItem.cpp |
+++ b/Source/core/rendering/RenderListItem.cpp |
@@ -25,6 +25,7 @@ |
#include "core/rendering/RenderListItem.h" |
#include "core/HTMLNames.h" |
+#include "core/dom/MarkerPseudoElement.h" |
#include "core/dom/NodeRenderingTraversal.h" |
#include "core/html/HTMLOListElement.h" |
#include "core/rendering/RenderListMarker.h" |
@@ -57,6 +58,9 @@ void RenderListItem::styleDidChange(StyleDifference diff, const RenderStyle* old |
{ |
RenderBlockFlow::styleDidChange(diff, oldStyle); |
+ if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) |
+ return; |
+ |
if (style()->listStyleType() != NoneListStyle |
|| (style()->listStyleImage() && !style()->listStyleImage()->errorOccurred())) { |
if (!m_marker) |
@@ -80,14 +84,12 @@ void RenderListItem::willBeDestroyed() |
void RenderListItem::insertedIntoTree() |
{ |
RenderBlockFlow::insertedIntoTree(); |
- |
updateListMarkerNumbers(); |
} |
void RenderListItem::willBeRemovedFromTree() |
{ |
RenderBlockFlow::willBeRemovedFromTree(); |
- |
updateListMarkerNumbers(); |
} |
@@ -219,60 +221,29 @@ void RenderListItem::updateValueNow() const |
bool RenderListItem::isEmpty() const |
{ |
- 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; |
+ if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) { |
+ PseudoElement* element = toElement(node())->pseudoElement(MARKER); |
+ return !(element && lastChild() != element->renderer()); |
} |
- |
- return 0; |
+ return lastChild() == m_marker; |
} |
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,20 @@ void RenderListItem::layout() |
{ |
ASSERT(needsLayout()); |
- if (m_marker) { |
+ if (RuntimeEnabledFeatures::listMarkerPseudoElementEnabled()) { |
+ PseudoElement* element = toElement(node())->pseudoElement(MARKER); |
+ if (element && element->renderer()) { |
+ ASSERT(element->renderer()->isListMarker()); |
+ RenderListMarker* marker = toRenderListMarker(element->renderer()); |
+ |
+ marker->updateMarginsAndContent(); |
+ |
+ // FIXME: Is this needed? |
+ 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 +320,36 @@ 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) |
+ return; |
+ |
+ ASSERT(marker->parent()); |
+ if (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 +358,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 +381,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 +404,10 @@ void RenderListItem::positionListMarker() |
} |
if (adjustOverflow) { |
- LayoutRect markerRect(LayoutPoint(markerLogicalLeft + lineOffset, blockOffset), m_marker->size()); |
+ LayoutRect markerRect(LayoutPoint(markerLogicalLeft + lineOffset, blockOffset), marker->size()); |
if (!style()->isHorizontalWritingMode()) |
markerRect = markerRect.transposedRect(); |
- RenderBox* o = m_marker; |
+ RenderBox* o = marker; |
bool propagateVisualOverflow = true; |
bool propagateLayoutOverflow = true; |
do { |
@@ -441,15 +440,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 +493,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(); |
Julien - ping for review
2015/02/04 01:56:34
This will need some explanations.
dsinclair
2015/02/04 04:41:33
This is the one bit that was needed from the old u
|
+ } |
+ } else if (m_marker) { |
updateMarkerLocation(); |
+ } |
} |
static RenderListItem* previousOrNextItem(bool isListReversed, Node* list, RenderListItem* item) |