Skip to content
Permalink
Browse files
2011-01-31 Carol Szabo <carol.szabo@nokia.com>
        Reviewed by David Hyatt.

        Code Changes only.

        It is needlessly expensive to find the generating node from an anonymous renderer of a pseudoelement.
        https://bugs.webkit.org/show_bug.cgi?id=53024

        No new tests. No change in functionality

        * rendering/RenderObject.h:
        (WebCore::RenderObject::before):
        (WebCore::RenderObject::after):
        (WebCore::RenderObject::generatingNode):
        Added new accessors for the use of the CSS 2.1 counters code
        (mainlyly)
        * rendering/RenderObjectChildList.cpp:
        (WebCore::beforeAfterContainer):
        (WebCore::RenderObjectChildList::invalidateCounters):
        (WebCore::RenderObjectChildList::before):
        (WebCore::RenderObjectChildList::after):
        Refactored the code to take advantage of the new accessors.
        (WebCore::RenderObjectChildList::updateBeforeAfterContent):
        Changed to store the generating node in the :before and :after
        renderers.
        * rendering/RenderObjectChildList.h:

Canonical link: https://commits.webkit.org/67327@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@77191 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Carol Szabo committed Feb 1, 2011
1 parent c91fa40 commit 3ed29a5b038bd9b4dab3fd2e9b4e54f7ddf0bb89
Showing 4 changed files with 116 additions and 60 deletions.
@@ -1,3 +1,31 @@
2011-01-31 Carol Szabo <carol.szabo@nokia.com>

Reviewed by David Hyatt.

Code Changes only.

It is needlessly expensive to find the generating node from an anonymous renderer of a pseudoelement.
https://bugs.webkit.org/show_bug.cgi?id=53024

No new tests. No change in functionality

* rendering/RenderObject.h:
(WebCore::RenderObject::before):
(WebCore::RenderObject::after):
(WebCore::RenderObject::generatingNode):
Added new accessors for the use of the CSS 2.1 counters code
(mainlyly)
* rendering/RenderObjectChildList.cpp:
(WebCore::beforeAfterContainer):
(WebCore::RenderObjectChildList::invalidateCounters):
(WebCore::RenderObjectChildList::before):
(WebCore::RenderObjectChildList::after):
Refactored the code to take advantage of the new accessors.
(WebCore::RenderObjectChildList::updateBeforeAfterContent):
Changed to store the generating node in the :before and :after
renderers.
* rendering/RenderObjectChildList.h:

2011-01-31 Krithigassree Sambamurthy <krithigassree.sambamurthy@nokia.com>

Reviewed by David Hyatt.
@@ -143,6 +143,18 @@ class RenderObject : public CachedResourceClient {
return children->lastChild();
return 0;
}
RenderObject* beforePseudoElementRenderer() const
{
if (const RenderObjectChildList* children = virtualChildren())
return children->beforePseudoElementRenderer(this);
return 0;
}
RenderObject* afterPseudoElementRenderer() const
{
if (const RenderObjectChildList* children = virtualChildren())
return children->afterPseudoElementRenderer(this);
return 0;
}
virtual RenderObjectChildList* virtualChildren() { return 0; }
virtual const RenderObjectChildList* virtualChildren() const { return 0; }

@@ -445,6 +457,11 @@ class RenderObject : public CachedResourceClient {
bool isRooted(RenderView** = 0);

Node* node() const { return m_isAnonymous ? 0 : m_node; }

// Returns the styled node that caused the generation of this renderer.
// This is the same as node() except for renderers of :before and :after
// pseudo elements for which their parent node is returned.
Node* generatingNode() const { return m_node == document() ? 0 : m_node; }
void setNode(Node* node) { m_node = node; }

Document* document() const { return m_node->document(); }
@@ -247,59 +247,6 @@ void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* c
owner->document()->axObjectCache()->childrenChanged(owner);
}

static RenderObject* beforeAfterContainer(RenderObject* container, PseudoId type)
{
if (type == BEFORE) {
// An anonymous (generated) inline run-in that has PseudoId BEFORE must come from a grandparent.
// Therefore we should skip these generated run-ins when checking our immediate children.
// If we don't find our :before child immediately, then we should check if we own a
// generated inline run-in in the next level of children.
RenderObject* first = container;
do {
// Skip list markers and generated run-ins
first = first->firstChild();
while (first && (first->isListMarker() || (first->isRenderInline() && first->isRunIn() && first->isAnonymous())))
first = first->nextSibling();
} while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);

if (!first)
return 0;

if (first->style()->styleType() == type)
return first;

// Check for a possible generated run-in, using run-in positioning rules.
// Skip inlines and floating / positioned blocks, and place as the first child.
first = container->firstChild();
if (!first->isRenderBlock())
return 0;
while (first && first->isFloatingOrPositioned())
first = first->nextSibling();
if (first) {
first = first->firstChild();
// We still need to skip any list markers that could exist before the run-in.
while (first && first->isListMarker())
first = first->nextSibling();
if (first && first->style()->styleType() == type && first->isRenderInline() && first->isRunIn() && first->isAnonymous())
return first;
}
return 0;
}

if (type == AFTER) {
RenderObject* last = container;
do {
last = last->lastChild();
} while (last && last->isAnonymous() && last->style()->styleType() == NOPSEUDO && !last->isListMarker());
if (last && last->style()->styleType() != type)
return 0;
return last;
}

ASSERT_NOT_REACHED();
return 0;
}

static RenderObject* findBeforeAfterParent(RenderObject* object)
{
// Only table parts need to search for the :before or :after parent
@@ -330,14 +277,63 @@ static void invalidateCountersInContainer(RenderObject* container, const AtomicS
}
}

void RenderObjectChildList::invalidateCounters(RenderObject* owner, const AtomicString& identifier)
void RenderObjectChildList::invalidateCounters(const RenderObject* owner, const AtomicString& identifier)
{
ASSERT(!owner->documentBeingDestroyed());
invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE), identifier);
invalidateCountersInContainer(beforeAfterContainer(owner, AFTER), identifier);
invalidateCountersInContainer(beforePseudoElementRenderer(owner), identifier);
invalidateCountersInContainer(afterPseudoElementRenderer(owner), identifier);
}

RenderObject* RenderObjectChildList::beforePseudoElementRenderer(const RenderObject* owner) const
{
// An anonymous (generated) inline run-in that has PseudoId BEFORE must come from a grandparent.
// Therefore we should skip these generated run-ins when checking our immediate children.
// If we don't find our :before child immediately, then we should check if we own a
// generated inline run-in in the next level of children.
RenderObject* first = const_cast<RenderObject*>(owner);
do {
// Skip list markers and generated run-ins
first = first->firstChild();
while (first && (first->isListMarker() || (first->isRenderInline() && first->isRunIn() && first->isAnonymous())))
first = first->nextSibling();
} while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);

if (!first)
return 0;

if (first->style()->styleType() == BEFORE)
return first;

// Check for a possible generated run-in, using run-in positioning rules.
// Skip inlines and floating / positioned blocks, and place as the first child.
first = owner->firstChild();
if (!first->isRenderBlock())
return 0;
while (first && first->isFloatingOrPositioned())
first = first->nextSibling();
if (first) {
first = first->firstChild();
// We still need to skip any list markers that could exist before the run-in.
while (first && first->isListMarker())
first = first->nextSibling();
if (first && first->style()->styleType() == BEFORE && first->isRenderInline() && first->isRunIn() && first->isAnonymous())
return first;
}
return 0;
}

RenderObject* RenderObjectChildList::afterPseudoElementRenderer(const RenderObject* owner) const
{
RenderObject* last = const_cast<RenderObject*>(owner);
do {
last = last->lastChild();
} while (last && last->isAnonymous() && last->style()->styleType() == NOPSEUDO && !last->isListMarker());
if (last && last->style()->styleType() != AFTER)
return 0;
return last;
}

void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject)
void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject)
{
// Double check that the document did in fact use generated content rules. Otherwise we should not have been called.
ASSERT(owner->document()->usesBeforeAfterRules());
@@ -350,7 +346,18 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
styledObject = owner;

RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type);
RenderObject* child = beforeAfterContainer(owner, type);
RenderObject* child;
switch (type) {
case BEFORE:
child = beforePseudoElementRenderer(owner);
break;
case AFTER:
child = afterPseudoElementRenderer(owner);
break;
default:
ASSERT_NOT_REACHED();
return;
}

// Whether or not we currently have generated content attached.
bool oldContentPresent = child;
@@ -464,6 +471,8 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
// Make a generated box that might be any display type now that we are able to drill down into children
// to find the original content properly.
generatedContentContainer = RenderObject::createObject(owner->document(), pseudoElementStyle);
ASSERT(styledObject->node()); // The styled object cannot be anonymous or else it could not have ':before' or ':after' pseudo elements.
generatedContentContainer->setNode(styledObject->node()); // This allows access to the generatingNode.
generatedContentContainer->setStyle(pseudoElementStyle);
owner->addChild(generatedContentContainer, insertBefore);
}
@@ -55,8 +55,10 @@ class RenderObjectChildList {
void appendChildNode(RenderObject* owner, RenderObject*, bool fullAppend = true);
void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool fullInsert = true);

void updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject = 0);
void invalidateCounters(RenderObject* owner, const AtomicString& identifier);
void updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject = 0);
RenderObject* beforePseudoElementRenderer(const RenderObject* owner) const;
RenderObject* afterPseudoElementRenderer(const RenderObject* owner) const;
void invalidateCounters(const RenderObject* owner, const AtomicString& identifier);

private:
RenderObject* m_firstChild;

0 comments on commit 3ed29a5

Please sign in to comment.