Title: [176032] trunk/Source/WebCore
Revision
176032
Author
[email protected]
Date
2014-11-12 12:16:47 -0800 (Wed, 12 Nov 2014)

Log Message

Minor improvements to RenderListItem
https://bugs.webkit.org/show_bug.cgi?id=138601

Reviewed by Darin Adler.

Make several minor improvements to RenderListItem and clean up the
code a bit.

No new tests, no behavior change.

* rendering/RenderListItem.cpp:
(WebCore::isHTMLListElement):
- Rename isList to isHTMLListElement() for clarity as it checks
  for HTMLOListElement and HTMLUListElement types
- Inline the function as it is short.
- Use is<HTML*Element>() for type checking
- Update the argument to take a Node& instead of an Element*. This
  is because the argument is expected to the non-null. Also using
  looser typing here allows us to use this utility function is one
  more place, without impacting performance as
  hasTagName(HTMLQualifiedName) is defined on Node.

(WebCore::enclosingList):
- Pass the argument as a reference instead of a pointer as it is
  expected to be non-null.
- Initialize firstNode before the loop to avoid the if (!firstNode)
  check for every iteration.

(WebCore::nextListItem):
- Take an Element as second argument instead of a RenderListItem*
  and provide convenience overloads so that we don't need to do
  null checks just because some calls sites call this function
  with 2 arguments and others with 1 argument. This way, we avoid
  unnecessary null checks as most call sites already do such
  checks (or have references).
- Transform the while loop into a for loop for clarity.
- Don't traverse an Element's subtree if the Element does not have
  a renderer as it is impossible of any of its descendant to have
  a renderer (and we are looking for a specific type of renderer).

(WebCore::previousListItem):
- Pass the item argument as a reference instead of a pointer as it
  is expected to be non-null.
- Reduce the scope of the |current| so that it is now declared
  inside the loop.

(WebCore::RenderListItem::updateItemValuesForOrderedList):
(WebCore::RenderListItem::itemCountForOrderedList):
- Pass argument as a reference instead of a pointer as it was expected
  to be non-null (There was an assertion in place to make sure of it).

(WebCore::RenderListItem::calcValue):
- Use is<HTMLOListElement>() instead of hasTagName().

(WebCore::getParentOfFirstLineBox):
- Rename variables to stop using abbreviations.
- Pass arguments as references instead of pointers as they are expected
  to be non-null.
- Remove the firstChild null check before the loop as it does not
  change behavior. The loop will abort early if firstChild is null
  and we will end up returning nullptr as well.
- Use is<>() more for type checking.
- Reuse the isHTMLListElement() utility function instead of duplicating
  its code inside this function.

(WebCore::firstNonMarkerChild):
- Pass argument as a reference as it is expected to be non-null.
- Rename variable from result to child for clarity, as we are traversing
  the children.

(WebCore::RenderListItem::markerTextWithSuffix):
- Use String appending instead of StringBuilder as it simplifies the
  code a lot and should not impact performance in this case.

(WebCore::RenderListItem::explicitValueChanged):
- Restructure the code a bit to do the |listNode| null check before the
  loop, now that nextListItem() takes a reference in argument. This is
  the only call site where we didn't already know that listNode is
  non-null.

(WebCore::previousOrNextItem):
- Mark this function as inline as it is short and called repeatedly.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (176031 => 176032)


--- trunk/Source/WebCore/ChangeLog	2014-11-12 20:09:42 UTC (rev 176031)
+++ trunk/Source/WebCore/ChangeLog	2014-11-12 20:16:47 UTC (rev 176032)
@@ -1,5 +1,90 @@
 2014-11-12  Chris Dumez  <[email protected]>
 
+        Minor improvements to RenderListItem
+        https://bugs.webkit.org/show_bug.cgi?id=138601
+
+        Reviewed by Darin Adler.
+
+        Make several minor improvements to RenderListItem and clean up the
+        code a bit.
+
+        No new tests, no behavior change.
+
+        * rendering/RenderListItem.cpp:
+        (WebCore::isHTMLListElement):
+        - Rename isList to isHTMLListElement() for clarity as it checks
+          for HTMLOListElement and HTMLUListElement types
+        - Inline the function as it is short.
+        - Use is<HTML*Element>() for type checking
+        - Update the argument to take a Node& instead of an Element*. This
+          is because the argument is expected to the non-null. Also using
+          looser typing here allows us to use this utility function is one
+          more place, without impacting performance as
+          hasTagName(HTMLQualifiedName) is defined on Node.
+
+        (WebCore::enclosingList):
+        - Pass the argument as a reference instead of a pointer as it is
+          expected to be non-null.
+        - Initialize firstNode before the loop to avoid the if (!firstNode)
+          check for every iteration.
+
+        (WebCore::nextListItem):
+        - Take an Element as second argument instead of a RenderListItem*
+          and provide convenience overloads so that we don't need to do
+          null checks just because some calls sites call this function
+          with 2 arguments and others with 1 argument. This way, we avoid
+          unnecessary null checks as most call sites already do such
+          checks (or have references).
+        - Transform the while loop into a for loop for clarity.
+        - Don't traverse an Element's subtree if the Element does not have
+          a renderer as it is impossible of any of its descendant to have
+          a renderer (and we are looking for a specific type of renderer).
+
+        (WebCore::previousListItem):
+        - Pass the item argument as a reference instead of a pointer as it
+          is expected to be non-null.
+        - Reduce the scope of the |current| so that it is now declared
+          inside the loop.
+
+        (WebCore::RenderListItem::updateItemValuesForOrderedList):
+        (WebCore::RenderListItem::itemCountForOrderedList):
+        - Pass argument as a reference instead of a pointer as it was expected
+          to be non-null (There was an assertion in place to make sure of it).
+
+        (WebCore::RenderListItem::calcValue):
+        - Use is<HTMLOListElement>() instead of hasTagName().
+
+        (WebCore::getParentOfFirstLineBox):
+        - Rename variables to stop using abbreviations.
+        - Pass arguments as references instead of pointers as they are expected
+          to be non-null.
+        - Remove the firstChild null check before the loop as it does not
+          change behavior. The loop will abort early if firstChild is null
+          and we will end up returning nullptr as well.
+        - Use is<>() more for type checking.
+        - Reuse the isHTMLListElement() utility function instead of duplicating
+          its code inside this function.
+
+        (WebCore::firstNonMarkerChild):
+        - Pass argument as a reference as it is expected to be non-null.
+        - Rename variable from result to child for clarity, as we are traversing
+          the children.
+
+        (WebCore::RenderListItem::markerTextWithSuffix):
+        - Use String appending instead of StringBuilder as it simplifies the
+          code a lot and should not impact performance in this case.
+
+        (WebCore::RenderListItem::explicitValueChanged):
+        - Restructure the code a bit to do the |listNode| null check before the
+          loop, now that nextListItem() takes a reference in argument. This is
+          the only call site where we didn't already know that listNode is
+          non-null.
+
+        (WebCore::previousOrNextItem):
+        - Mark this function as inline as it is short and called repeatedly.
+
+2014-11-12  Chris Dumez  <[email protected]>
+
         Speed up HTMLTextFormControlElement::setInnerTextValue() a bit
         https://bugs.webkit.org/show_bug.cgi?id=138619
 

Modified: trunk/Source/WebCore/html/HTMLOListElement.cpp (176031 => 176032)


--- trunk/Source/WebCore/html/HTMLOListElement.cpp	2014-11-12 20:09:42 UTC (rev 176031)
+++ trunk/Source/WebCore/html/HTMLOListElement.cpp	2014-11-12 20:16:47 UTC (rev 176032)
@@ -106,12 +106,12 @@
 
 void HTMLOListElement::updateItemValues()
 {
-    RenderListItem::updateItemValuesForOrderedList(this);
+    RenderListItem::updateItemValuesForOrderedList(*this);
 }
 
 void HTMLOListElement::recalculateItemCount()
 {
-    m_itemCount = RenderListItem::itemCountForOrderedList(this);
+    m_itemCount = RenderListItem::itemCountForOrderedList(*this);
     m_shouldRecalculateItemCount = false;
 }
 

Modified: trunk/Source/WebCore/rendering/RenderListItem.cpp (176031 => 176032)


--- trunk/Source/WebCore/rendering/RenderListItem.cpp	2014-11-12 20:09:42 UTC (rev 176031)
+++ trunk/Source/WebCore/rendering/RenderListItem.cpp	2014-11-12 20:16:47 UTC (rev 176032)
@@ -33,6 +33,7 @@
 #include "RenderInline.h"
 #include "RenderListMarker.h"
 #include "RenderMultiColumnFlowThread.h"
+#include "RenderTable.h"
 #include "RenderView.h"
 #include "StyleInheritedData.h"
 #include <wtf/StackStats.h>
@@ -99,23 +100,21 @@
     updateListMarkerNumbers();
 }
 
-static bool isList(const Element* element)
+static inline bool isHTMLListElement(const Node& node)
 {
-    return element->hasTagName(ulTag) || element->hasTagName(olTag);
+    return is<HTMLUListElement>(node) || is<HTMLOListElement>(node);
 }
 
 // Returns the enclosing list with respect to the DOM order.
-static Element* enclosingList(const RenderListItem* listItem)
+static Element* enclosingList(const RenderListItem& listItem)
 {
-    Element& listItemElement = listItem->element();
-    Element* firstNode = nullptr;
+    Element& listItemElement = listItem.element();
     Element* parent = is<PseudoElement>(listItemElement) ? downcast<PseudoElement>(listItemElement).hostElement() : listItemElement.parentElement();
+    Element* firstNode = parent;
     // We use parentNode because the enclosing list could be a ShadowRoot that's not Element.
     for (; parent; parent = parent->parentElement()) {
-        if (isList(parent))
+        if (isHTMLListElement(*parent))
             return parent;
-        if (!firstNode)
-            firstNode = parent;
     }
 
     // If there's no actual <ul> or <ol> list element, then the first found
@@ -125,41 +124,43 @@
 }
 
 // Returns the next list item with respect to the DOM order.
-static RenderListItem* nextListItem(const Element* listNode, const RenderListItem* item = nullptr)
+static RenderListItem* nextListItem(const Element& listNode, const Element& element)
 {
-    if (!listNode)
-        return nullptr;
-
-    const Element* current = item ? &item->element() : listNode;
-    current = ElementTraversal::nextIncludingPseudo(current, listNode);
-
-    while (current) {
-        if (isList(current)) {
-            // We've found a nested, independent list: nothing to do here.
-            current = ElementTraversal::nextIncludingPseudoSkippingChildren(current, listNode);
+    for (const Element* next = ElementTraversal::nextIncludingPseudo(&element, &listNode); next; ) {
+        auto* renderer = next->renderer();
+        if (!renderer || isHTMLListElement(*next)) {
+            // We've found a nested, independent list or an unrendered Element : nothing to do here.
+            next = ElementTraversal::nextIncludingPseudoSkippingChildren(next, &listNode);
             continue;
         }
 
-        RenderElement* renderer = current->renderer();
-        if (is<RenderListItem>(renderer))
+        if (is<RenderListItem>(*renderer))
             return downcast<RenderListItem>(renderer);
 
-        // FIXME: Can this be optimized to skip the children of the elements without a renderer?
-        current = ElementTraversal::nextIncludingPseudo(current, listNode);
+        next = ElementTraversal::nextIncludingPseudo(next, &listNode);
     }
 
     return nullptr;
 }
 
+static inline RenderListItem* nextListItem(const Element& listNode, const RenderListItem& item)
+{
+    return nextListItem(listNode, item.element());
+}
+
+static inline RenderListItem* nextListItem(const Element& listNode)
+{
+    return nextListItem(listNode, listNode);
+}
+
 // Returns the previous list item with respect to the DOM order.
-static RenderListItem* previousListItem(const Element* listNode, const RenderListItem* item)
+static RenderListItem* previousListItem(const Element* listNode, const RenderListItem& item)
 {
-    Element* current = &item->element();
-    for (current = ElementTraversal::previousIncludingPseudo(current, listNode); current; current = ElementTraversal::previousIncludingPseudo(current, listNode)) {
+    for (const Element* current = ElementTraversal::previousIncludingPseudo(&item.element(), listNode); current; current = ElementTraversal::previousIncludingPseudo(current, listNode)) {
         RenderElement* renderer = current->renderer();
         if (!is<RenderListItem>(renderer))
             continue;
-        Element* otherList = enclosingList(downcast<RenderListItem>(renderer));
+        Element* otherList = enclosingList(downcast<RenderListItem>(*renderer));
         // This item is part of our current list, so it's what we're looking for.
         if (listNode == otherList)
             return downcast<RenderListItem>(renderer);
@@ -173,22 +174,17 @@
     return nullptr;
 }
 
-void RenderListItem::updateItemValuesForOrderedList(const HTMLOListElement* listNode)
+void RenderListItem::updateItemValuesForOrderedList(const HTMLOListElement& listNode)
 {
-    ASSERT(listNode);
-
-    for (RenderListItem* listItem = nextListItem(listNode); listItem; listItem = nextListItem(listNode, listItem))
+    for (RenderListItem* listItem = nextListItem(listNode); listItem; listItem = nextListItem(listNode, *listItem))
         listItem->updateValue();
 }
 
-unsigned RenderListItem::itemCountForOrderedList(const HTMLOListElement* listNode)
+unsigned RenderListItem::itemCountForOrderedList(const HTMLOListElement& listNode)
 {
-    ASSERT(listNode);
-
     unsigned itemCount = 0;
-    for (RenderListItem* listItem = nextListItem(listNode); listItem; listItem = nextListItem(listNode, listItem))
-        itemCount++;
-
+    for (RenderListItem* listItem = nextListItem(listNode); listItem; listItem = nextListItem(listNode, *listItem))
+        ++itemCount;
     return itemCount;
 }
 
@@ -197,15 +193,15 @@
     if (m_hasExplicitValue)
         return m_explicitValue;
 
-    Element* list = enclosingList(this);
-    HTMLOListElement* oListElement = (list && list->hasTagName(olTag)) ? downcast<HTMLOListElement>(list) : nullptr;
+    Element* list = enclosingList(*this);
+    HTMLOListElement* oListElement = is<HTMLOListElement>(list) ? downcast<HTMLOListElement>(list) : nullptr;
     int valueStep = 1;
     if (oListElement && oListElement->isReversed())
         valueStep = -1;
 
     // FIXME: This recurses to a possible depth of the length of the list.
     // That's not good -- we need to change this to an iterative algorithm.
-    if (RenderListItem* previousItem = previousListItem(list, this))
+    if (RenderListItem* previousItem = previousListItem(list, *this))
         return previousItem->value() + valueStep;
 
     if (oListElement)
@@ -225,31 +221,26 @@
     return lastChild() == m_marker;
 }
 
-static RenderBlock* getParentOfFirstLineBox(RenderBlock* curr, RenderObject* marker)
+static RenderBlock* getParentOfFirstLineBox(RenderBlock& current, 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)
+    bool inQuirksMode = current.document().inQuirksMode();
+    for (RenderObject* child = current.firstChild(); child; child = child->nextSibling()) {
+        if (child == &marker)
             continue;
 
-        if (currChild->isInline() && (!is<RenderInline>(*currChild) || curr->generatesLineBoxesForInlineChild(currChild)))
-            return curr;
+        if (child->isInline() && (!is<RenderInline>(*child) || current.generatesLineBoxesForInlineChild(child)))
+            return &current;
 
-        if (currChild->isFloating() || currChild->isOutOfFlowPositioned())
+        if (child->isFloating() || child->isOutOfFlowPositioned())
             continue;
 
-        if (currChild->isTable() || !is<RenderBlock>(*currChild) || (is<RenderBox>(*currChild) && downcast<RenderBox>(*currChild).isWritingModeRoot()))
+        if (is<RenderTable>(*child) || !is<RenderBlock>(*child) || (is<RenderBox>(*child) && downcast<RenderBox>(*child).isWritingModeRoot()))
             break;
 
-        if (curr->isListItem() && inQuirksMode && currChild->node() &&
-            (is<HTMLUListElement>(*currChild->node()) || is<HTMLOListElement>(*currChild->node())))
+        if (is<RenderListItem>(current) && inQuirksMode && child->node() && isHTMLListElement(*child->node()))
             break;
 
-        if (RenderBlock* lineBox = getParentOfFirstLineBox(downcast<RenderBlock>(currChild), marker))
+        if (RenderBlock* lineBox = getParentOfFirstLineBox(downcast<RenderBlock>(*child), marker))
             return lineBox;
     }
 
@@ -265,12 +256,12 @@
     }
 }
 
-static RenderObject* firstNonMarkerChild(RenderBlock* parent)
+static RenderObject* firstNonMarkerChild(RenderBlock& parent)
 {
-    RenderObject* result = parent->firstChild();
-    while (result && result->isListMarker())
-        result = result->nextSibling();
-    return result;
+    RenderObject* child = parent.firstChild();
+    while (is<RenderListMarker>(child))
+        child = child->nextSibling();
+    return child;
 }
 
 void RenderListItem::insertOrMoveMarkerRendererIfNeeded()
@@ -280,7 +271,7 @@
         return;
 
     RenderElement* currentParent = m_marker->parent();
-    RenderBlock* newParent = getParentOfFirstLineBox(this, m_marker);
+    RenderBlock* newParent = getParentOfFirstLineBox(*this, *m_marker);
     if (!newParent) {
         // If the marker is currently contained inside an anonymous box,
         // then we are the only item in that anonymous box (since no line box
@@ -299,7 +290,7 @@
         // containers other than ourselves, so we need to disable LayoutState.
         LayoutStateDisabler layoutStateDisabler(&view());
         m_marker->removeFromParent();
-        newParent->addChild(m_marker, firstNonMarkerChild(newParent));
+        newParent->addChild(m_marker, firstNonMarkerChild(*newParent));
         m_marker->updateMarginsAndContent();
         // If current parent is an anonymous block that has lost all its children, destroy it.
         if (currentParent && currentParent->isAnonymousBlock() && !currentParent->firstChild() && !downcast<RenderBlock>(*currentParent).continuation())
@@ -452,28 +443,21 @@
 
     // Append the suffix for the marker in the right place depending
     // on the direction of the text (right-to-left or left-to-right).
-
-    const String& markerText = m_marker->text();
-    const String markerSuffix = m_marker->suffix();
-    StringBuilder result;
-
-    if (!m_marker->style().isLeftToRightDirection())
-        result.append(markerSuffix);
-
-    result.append(markerText);
-
     if (m_marker->style().isLeftToRightDirection())
-        result.append(markerSuffix);
-
-    return result.toString();
+        return m_marker->text() + m_marker->suffix();
+    return m_marker->suffix() + m_marker->text();
 }
 
 void RenderListItem::explicitValueChanged()
 {
     if (m_marker)
         m_marker->setNeedsLayoutAndPrefWidthsRecalc();
-    Element* listNode = enclosingList(this);
-    for (RenderListItem* item = this; item; item = nextListItem(listNode, item))
+
+    updateValue();
+    Element* listNode = enclosingList(*this);
+    if (!listNode)
+        return;
+    for (RenderListItem* item = nextListItem(*listNode, *this); item; item = nextListItem(*listNode, *item))
         item->updateValue();
 }
 
@@ -496,25 +480,25 @@
     explicitValueChanged();
 }
 
-static RenderListItem* previousOrNextItem(bool isListReversed, Element* list, RenderListItem* item)
+static inline RenderListItem* previousOrNextItem(bool isListReversed, Element& list, RenderListItem& item)
 {
-    return isListReversed ? previousListItem(list, item) : nextListItem(list, item);
+    return isListReversed ? previousListItem(&list, item) : nextListItem(list, item);
 }
 
 void RenderListItem::updateListMarkerNumbers()
 {
-    Element* listNode = enclosingList(this);
+    Element* listNode = enclosingList(*this);
     // The list node can be the shadow root which has no renderer.
     if (!listNode)
         return;
 
     bool isListReversed = false;
-    HTMLOListElement* oListElement = (listNode && listNode->hasTagName(olTag)) ? downcast<HTMLOListElement>(listNode) : nullptr;
-    if (oListElement) {
-        oListElement->itemCountChanged();
-        isListReversed = oListElement->isReversed();
+    if (is<HTMLOListElement>(*listNode)) {
+        HTMLOListElement& oListElement = downcast<HTMLOListElement>(*listNode);
+        oListElement.itemCountChanged();
+        isListReversed = oListElement.isReversed();
     }
-    for (RenderListItem* item = previousOrNextItem(isListReversed, listNode, this); item; item = previousOrNextItem(isListReversed, listNode, item)) {
+    for (RenderListItem* item = previousOrNextItem(isListReversed, *listNode, *this); item; item = previousOrNextItem(isListReversed, *listNode, *item)) {
         if (!item->m_isValueUpToDate) {
             // If an item has been marked for update before, we can safely
             // assume that all the following ones have too.

Modified: trunk/Source/WebCore/rendering/RenderListItem.h (176031 => 176032)


--- trunk/Source/WebCore/rendering/RenderListItem.h	2014-11-12 20:09:42 UTC (rev 176031)
+++ trunk/Source/WebCore/rendering/RenderListItem.h	2014-11-12 20:16:47 UTC (rev 176032)
@@ -53,8 +53,8 @@
 
     void updateListMarkerNumbers();
 
-    static void updateItemValuesForOrderedList(const HTMLOListElement*);
-    static unsigned itemCountForOrderedList(const HTMLOListElement*);
+    static void updateItemValuesForOrderedList(const HTMLOListElement&);
+    static unsigned itemCountForOrderedList(const HTMLOListElement&);
 
     void didDestroyListMarker() { m_marker = nullptr; }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to