<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[172409] trunk/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/172409">172409</a></dd>
<dt>Author</dt> <dd>antti@apple.com</dd>
<dt>Date</dt> <dd>2014-08-11 13:42:16 -0700 (Mon, 11 Aug 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Pass inherited style only when resolving tree style
https://bugs.webkit.org/show_bug.cgi?id=135799
Reviewed by Andreas Kling.
No need to pass around the style parent element.
* dom/ContainerNode.h:
(WebCore::ContainerNode::childShouldCreateRenderer): Deleted.
* dom/Element.cpp:
(WebCore::Element::childShouldCreateRenderer):
* dom/Element.h:
* style/StyleResolveTree.cpp:
(WebCore::Style::RenderTreePosition::parent):
(WebCore::Style::nextSiblingRenderer):
(WebCore::Style::RenderTreePosition::RenderTreePosition):
(WebCore::Style::RenderTreePosition::computeNextSibling):
(WebCore::Style::shouldCreateRenderer):
(WebCore::Style::styleForElement):
(WebCore::Style::createRendererIfNeeded):
(WebCore::Style::textRendererIsNeeded):
(WebCore::Style::createTextRendererIfNeeded):
(WebCore::Style::attachTextRenderer):
(WebCore::Style::updateTextRendererAfterContentChange):
(WebCore::Style::attachChildren):
(WebCore::Style::attachDistributedChildren):
(WebCore::Style::attachShadowRoot):
(WebCore::Style::attachBeforeOrAfterPseudoElementIfNeeded):
(WebCore::Style::attachRenderTree):
(WebCore::Style::resolveLocal):
(WebCore::Style::resolveTextNode):
(WebCore::Style::resolveShadowTree):
(WebCore::Style::updateBeforeOrAfterPseudoElement):
(WebCore::Style::resolveTree):
* svg/SVGDocument.cpp:
(WebCore::SVGDocument::childShouldCreateRenderer): Deleted.
Implement this in SVGSVGElement::rendererIsNeeded instead.
* svg/SVGDocument.h:
* svg/SVGSVGElement.cpp:
(WebCore::SVGSVGElement::rendererIsNeeded):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomContainerNodeh">trunk/Source/WebCore/dom/ContainerNode.h</a></li>
<li><a href="#trunkSourceWebCoredomElementcpp">trunk/Source/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementh">trunk/Source/WebCore/dom/Element.h</a></li>
<li><a href="#trunkSourceWebCorestyleStyleResolveTreecpp">trunk/Source/WebCore/style/StyleResolveTree.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGAElementcpp">trunk/Source/WebCore/svg/SVGAElement.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGDocumentcpp">trunk/Source/WebCore/svg/SVGDocument.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGDocumenth">trunk/Source/WebCore/svg/SVGDocument.h</a></li>
<li><a href="#trunkSourceWebCoresvgSVGSVGElementcpp">trunk/Source/WebCore/svg/SVGSVGElement.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (172408 => 172409)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-08-11 20:24:19 UTC (rev 172408)
+++ trunk/Source/WebCore/ChangeLog        2014-08-11 20:42:16 UTC (rev 172409)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2014-08-11 Antti Koivisto <antti@apple.com>
+
+ Pass inherited style only when resolving tree style
+ https://bugs.webkit.org/show_bug.cgi?id=135799
+
+ Reviewed by Andreas Kling.
+
+ No need to pass around the style parent element.
+
+ * dom/ContainerNode.h:
+ (WebCore::ContainerNode::childShouldCreateRenderer): Deleted.
+ * dom/Element.cpp:
+ (WebCore::Element::childShouldCreateRenderer):
+ * dom/Element.h:
+ * style/StyleResolveTree.cpp:
+ (WebCore::Style::RenderTreePosition::parent):
+ (WebCore::Style::nextSiblingRenderer):
+ (WebCore::Style::RenderTreePosition::RenderTreePosition):
+ (WebCore::Style::RenderTreePosition::computeNextSibling):
+ (WebCore::Style::shouldCreateRenderer):
+ (WebCore::Style::styleForElement):
+ (WebCore::Style::createRendererIfNeeded):
+ (WebCore::Style::textRendererIsNeeded):
+ (WebCore::Style::createTextRendererIfNeeded):
+ (WebCore::Style::attachTextRenderer):
+ (WebCore::Style::updateTextRendererAfterContentChange):
+ (WebCore::Style::attachChildren):
+ (WebCore::Style::attachDistributedChildren):
+ (WebCore::Style::attachShadowRoot):
+ (WebCore::Style::attachBeforeOrAfterPseudoElementIfNeeded):
+ (WebCore::Style::attachRenderTree):
+ (WebCore::Style::resolveLocal):
+ (WebCore::Style::resolveTextNode):
+ (WebCore::Style::resolveShadowTree):
+ (WebCore::Style::updateBeforeOrAfterPseudoElement):
+ (WebCore::Style::resolveTree):
+ * svg/SVGDocument.cpp:
+ (WebCore::SVGDocument::childShouldCreateRenderer): Deleted.
+
+ Implement this in SVGSVGElement::rendererIsNeeded instead.
+
+ * svg/SVGDocument.h:
+ * svg/SVGSVGElement.cpp:
+ (WebCore::SVGSVGElement::rendererIsNeeded):
+
</ins><span class="cx"> 2014-08-11 Yusuke Suzuki <utatane.tea@gmail.com>
</span><span class="cx">
</span><span class="cx"> CSS JIT: support :scope
</span></span></pre></div>
<a id="trunkSourceWebCoredomContainerNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ContainerNode.h (172408 => 172409)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ContainerNode.h        2014-08-11 20:24:19 UTC (rev 172408)
+++ trunk/Source/WebCore/dom/ContainerNode.h        2014-08-11 20:42:16 UTC (rev 172409)
</span><span class="lines">@@ -121,8 +121,6 @@
</span><span class="cx">
</span><span class="cx"> void disconnectDescendantFrames();
</span><span class="cx">
</span><del>- virtual bool childShouldCreateRenderer(const Node&) const { return true; }
-
</del><span class="cx"> using Node::setAttributeEventListener;
</span><span class="cx"> void setAttributeEventListener(const AtomicString& eventType, const QualifiedName& attributeName, const AtomicString& value);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.cpp (172408 => 172409)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.cpp        2014-08-11 20:24:19 UTC (rev 172408)
+++ trunk/Source/WebCore/dom/Element.cpp        2014-08-11 20:42:16 UTC (rev 172409)
</span><span class="lines">@@ -2458,7 +2458,7 @@
</span><span class="cx"> ASSERT(!isSVGElement());
</span><span class="cx"> return child.hasTagName(SVGNames::svgTag) && toSVGElement(child).isValid();
</span><span class="cx"> }
</span><del>- return ContainerNode::childShouldCreateRenderer(child);
</del><ins>+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(FULLSCREEN_API)
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.h (172408 => 172409)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.h        2014-08-11 20:24:19 UTC (rev 172408)
+++ trunk/Source/WebCore/dom/Element.h        2014-08-11 20:42:16 UTC (rev 172409)
</span><span class="lines">@@ -488,7 +488,7 @@
</span><span class="cx"> // to event listeners, and prevents DOMActivate events from being sent at all.
</span><span class="cx"> virtual bool isDisabledFormControl() const { return false; }
</span><span class="cx">
</span><del>- virtual bool childShouldCreateRenderer(const Node&) const override;
</del><ins>+ virtual bool childShouldCreateRenderer(const Node&) const;
</ins><span class="cx">
</span><span class="cx"> bool hasPendingResources() const;
</span><span class="cx"> void setHasPendingResources();
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleResolveTreecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleResolveTree.cpp (172408 => 172409)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleResolveTree.cpp        2014-08-11 20:24:19 UTC (rev 172408)
+++ trunk/Source/WebCore/style/StyleResolveTree.cpp        2014-08-11 20:42:16 UTC (rev 172409)
</span><span class="lines">@@ -64,16 +64,18 @@
</span><span class="cx">
</span><span class="cx"> class RenderTreePosition {
</span><span class="cx"> public:
</span><del>- RenderTreePosition(RenderElement* parent);
</del><ins>+ explicit RenderTreePosition(RenderView&);
+ explicit RenderTreePosition(RenderElement* parent);
</ins><span class="cx"> RenderTreePosition(RenderElement* parent, RenderObject* nextSibling);
</span><span class="cx">
</span><span class="cx"> RenderElement* parent() { return m_parent; }
</span><ins>+ const RenderElement* parent() const { return m_parent; }
</ins><span class="cx">
</span><span class="cx"> void insert(RenderObject&);
</span><span class="cx"> bool canInsert(RenderElement&) const;
</span><span class="cx"> bool canInsert(RenderText&) const;
</span><span class="cx">
</span><del>- void computeNextSibling(const Node&, ContainerNode& renderingParentNode);
</del><ins>+ void computeNextSibling(const Node&);
</ins><span class="cx"> void invalidateNextSibling(const RenderObject&);
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="lines">@@ -85,11 +87,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> };
</span><span class="cx">
</span><del>-static void attachRenderTree(Element&, ContainerNode& renderingParentNode, RenderTreePosition&, PassRefPtr<RenderStyle>);
-static void attachTextRenderer(Text&, ContainerNode& renderingParentNode, RenderTreePosition&);
</del><ins>+static void attachRenderTree(Element&, RenderStyle* inheritedStyle, RenderTreePosition&, PassRefPtr<RenderStyle>);
+static void attachTextRenderer(Text&, RenderTreePosition&);
</ins><span class="cx"> static void detachRenderTree(Element&, DetachType);
</span><del>-static void resolveTextNode(Text&, ContainerNode& renderingParentNode, RenderTreePosition&);
-static void resolveTree(Element&, ContainerNode& renderingParentNode, RenderTreePosition&, Change);
</del><ins>+static void resolveTextNode(Text&, RenderTreePosition&);
+static void resolveTree(Element&, RenderStyle* inheritedStyle, RenderTreePosition&, Change);
</ins><span class="cx">
</span><span class="cx"> Change determineChange(const RenderStyle* s1, const RenderStyle* s2)
</span><span class="cx"> {
</span><span class="lines">@@ -152,29 +154,33 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static RenderObject* nextSiblingRenderer(const Node& node, const ContainerNode& renderingParentNode)
</del><ins>+static RenderObject* nextSiblingRenderer(const Node& node, const RenderElement& parentRenderer)
</ins><span class="cx"> {
</span><del>- if (!renderingParentNode.isElementNode())
</del><ins>+ if (!parentRenderer.element())
</ins><span class="cx"> return nullptr;
</span><del>- const Element& renderingParentElement = toElement(renderingParentNode);
- // Avoid an O(N^2) problem with this function by not checking for
- // nextRenderer() when the parent element hasn't attached yet.
- // FIXME: Why would we get here anyway if parent is not attached?
- if (!renderingParentElement.renderer())
- return nullptr;
</del><span class="cx"> if (node.isAfterPseudoElement())
</span><span class="cx"> return nullptr;
</span><del>- Node* sibling = node.isBeforePseudoElement() ? NodeRenderingTraversal::firstChild(&renderingParentNode) : NodeRenderingTraversal::nextSibling(&node);
</del><ins>+ Node* sibling = node.isBeforePseudoElement() ? NodeRenderingTraversal::firstChild(parentRenderer.element()) : NodeRenderingTraversal::nextSibling(&node);
</ins><span class="cx"> for (; sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
</span><span class="cx"> RenderObject* renderer = sibling->renderer();
</span><span class="cx"> if (renderer && !isRendererReparented(renderer))
</span><span class="cx"> return renderer;
</span><span class="cx"> }
</span><del>- if (PseudoElement* after = renderingParentElement.afterPseudoElement())
</del><ins>+ if (PseudoElement* after = parentRenderer.element()->afterPseudoElement())
</ins><span class="cx"> return after->renderer();
</span><span class="cx"> return nullptr;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+RenderTreePosition::RenderTreePosition(RenderView& root)
+ : m_parent(&root)
+ , m_nextSibling(nullptr)
+ , m_hasValidNextSibling(true)
+#if !ASSERT_DISABLED
+ , m_assertionLimitCounter(0)
+#endif
+{
+}
+
</ins><span class="cx"> RenderTreePosition::RenderTreePosition(RenderElement* parent)
</span><span class="cx"> : m_parent(parent)
</span><span class="cx"> , m_nextSibling(nullptr)
</span><span class="lines">@@ -216,15 +222,16 @@
</span><span class="cx"> m_parent->addChild(&renderer, m_nextSibling);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void RenderTreePosition::computeNextSibling(const Node& node, ContainerNode& renderingParentNode)
</del><ins>+void RenderTreePosition::computeNextSibling(const Node& node)
</ins><span class="cx"> {
</span><ins>+ ASSERT(m_parent);
</ins><span class="cx"> ASSERT(!node.renderer());
</span><span class="cx"> if (m_hasValidNextSibling) {
</span><span class="cx"> // Stop validating at some point so the assert doesn't make us O(N^2) on debug builds.
</span><del>- ASSERT(++m_assertionLimitCounter > 20 || nextSiblingRenderer(node, renderingParentNode) == m_nextSibling);
</del><ins>+ ASSERT(m_parent->isRenderView() || ++m_assertionLimitCounter > 20 || nextSiblingRenderer(node, *m_parent) == m_nextSibling);
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><del>- m_nextSibling = nextSiblingRenderer(node, renderingParentNode);
</del><ins>+ m_nextSibling = nextSiblingRenderer(node, *m_parent);
</ins><span class="cx"> m_hasValidNextSibling = true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -236,28 +243,26 @@
</span><span class="cx"> m_hasValidNextSibling = false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static bool shouldCreateRenderer(const Element& element, const ContainerNode& renderingParent)
</del><ins>+static bool shouldCreateRenderer(const Element& element, const RenderElement* parentRenderer)
</ins><span class="cx"> {
</span><span class="cx"> if (!element.document().shouldCreateRenderers())
</span><span class="cx"> return false;
</span><del>- RenderObject* parentRenderer = renderingParent.renderer();
</del><span class="cx"> if (!parentRenderer)
</span><span class="cx"> return false;
</span><span class="cx"> if (!parentRenderer->canHaveChildren() && !(element.isPseudoElement() && parentRenderer->canHaveGeneratedChildren()))
</span><span class="cx"> return false;
</span><del>- if (!renderingParent.childShouldCreateRenderer(element))
</del><ins>+ if (parentRenderer->element() && !parentRenderer->element()->childShouldCreateRenderer(element))
</ins><span class="cx"> return false;
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static PassRef<RenderStyle> styleForElement(Element& element, ContainerNode& renderingParentNode)
</del><ins>+static PassRef<RenderStyle> styleForElement(Element& element, RenderStyle* inheritedStyle)
</ins><span class="cx"> {
</span><del>- RenderStyle* parentStyle = renderingParentNode.renderStyle();
- if (element.hasCustomStyleResolveCallbacks() && parentStyle) {
- if (RefPtr<RenderStyle> style = element.customStyleForRenderer(*parentStyle))
</del><ins>+ if (element.hasCustomStyleResolveCallbacks() && inheritedStyle) {
+ if (RefPtr<RenderStyle> style = element.customStyleForRenderer(*inheritedStyle))
</ins><span class="cx"> return style.releaseNonNull();
</span><span class="cx"> }
</span><del>- return element.document().ensureStyleResolver().styleForElement(&element, parentStyle);
</del><ins>+ return element.document().ensureStyleResolver().styleForElement(&element, inheritedStyle);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(CSS_REGIONS)
</span><span class="lines">@@ -273,17 +278,17 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>-static void createRendererIfNeeded(Element& element, ContainerNode& renderingParentNode, RenderTreePosition& renderTreePosition, PassRefPtr<RenderStyle> resolvedStyle)
</del><ins>+static void createRendererIfNeeded(Element& element, RenderStyle* inheritedStyle, RenderTreePosition& renderTreePosition, PassRefPtr<RenderStyle> resolvedStyle)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(!element.renderer());
</span><span class="cx">
</span><span class="cx"> RefPtr<RenderStyle> style = resolvedStyle;
</span><span class="cx">
</span><del>- if (!shouldCreateRenderer(element, renderingParentNode))
</del><ins>+ if (!shouldCreateRenderer(element, renderTreePosition.parent()))
</ins><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> if (!style)
</span><del>- style = styleForElement(element, renderingParentNode);
</del><ins>+ style = styleForElement(element, inheritedStyle);
</ins><span class="cx">
</span><span class="cx"> RenderNamedFlowThread* parentFlowRenderer = 0;
</span><span class="cx"> #if ENABLE(CSS_REGIONS)
</span><span class="lines">@@ -293,7 +298,7 @@
</span><span class="cx"> if (!element.rendererIsNeeded(*style))
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- renderTreePosition.computeNextSibling(element, renderingParentNode);
</del><ins>+ renderTreePosition.computeNextSibling(element);
</ins><span class="cx">
</span><span class="cx"> RenderTreePosition insertionPosition = parentFlowRenderer
</span><span class="cx"> ? RenderTreePosition(parentFlowRenderer, parentFlowRenderer->nextRendererForElement(element))
</span><span class="lines">@@ -370,22 +375,19 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static bool textRendererIsNeeded(const Text& textNode, ContainerNode& renderingParentNode)
</del><ins>+static bool textRendererIsNeeded(const Text& textNode, const RenderTreePosition& renderTreePosition)
</ins><span class="cx"> {
</span><del>- if (!renderingParentNode.renderer())
</del><ins>+ if (!renderTreePosition.parent())
</ins><span class="cx"> return false;
</span><del>- RenderElement& parentRenderer = *renderingParentNode.renderer();
</del><ins>+ const RenderElement& parentRenderer = *renderTreePosition.parent();
</ins><span class="cx"> if (!parentRenderer.canHaveChildren())
</span><span class="cx"> return false;
</span><del>- if (!renderingParentNode.childShouldCreateRenderer(textNode))
</del><ins>+ if (parentRenderer.element() && !parentRenderer.element()->childShouldCreateRenderer(textNode))
</ins><span class="cx"> return false;
</span><del>-
</del><span class="cx"> if (textNode.isEditingText())
</span><span class="cx"> return true;
</span><span class="cx"> if (!textNode.length())
</span><span class="cx"> return false;
</span><del>- if (parentRenderer.style().display() == NONE)
- return false;
</del><span class="cx"> if (!textNode.containsOnlyWhitespace())
</span><span class="cx"> return true;
</span><span class="cx"> // This text node has nothing but white space. We may still need a renderer in some cases.
</span><span class="lines">@@ -409,7 +411,7 @@
</span><span class="cx"> RenderObject* first = parentRenderer.firstChild();
</span><span class="cx"> while (first && first->isFloatingOrOutOfFlowPositioned())
</span><span class="cx"> first = first->nextSibling();
</span><del>- RenderObject* nextRenderer = nextSiblingRenderer(textNode, *textNode.parentNode());
</del><ins>+ RenderObject* nextRenderer = nextSiblingRenderer(textNode, parentRenderer);
</ins><span class="cx"> if (!first || nextRenderer == first) {
</span><span class="cx"> // Whitespace at the start of a block just goes away. Don't even make a render object for this text.
</span><span class="cx"> return false;
</span><span class="lines">@@ -418,17 +420,17 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static void createTextRendererIfNeeded(Text& textNode, ContainerNode& renderingParentNode, RenderTreePosition& renderTreePosition)
</del><ins>+static void createTextRendererIfNeeded(Text& textNode, RenderTreePosition& renderTreePosition)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(!textNode.renderer());
</span><span class="cx">
</span><del>- if (!textRendererIsNeeded(textNode, renderingParentNode))
</del><ins>+ if (!textRendererIsNeeded(textNode, renderTreePosition))
</ins><span class="cx"> return;
</span><span class="cx">
</span><del>- auto newRenderer = textNode.createTextRenderer(*renderingParentNode.renderStyle());
</del><ins>+ auto newRenderer = textNode.createTextRenderer(renderTreePosition.parent()->style());
</ins><span class="cx"> ASSERT(newRenderer);
</span><span class="cx">
</span><del>- renderTreePosition.computeNextSibling(textNode, renderingParentNode);
</del><ins>+ renderTreePosition.computeNextSibling(textNode);
</ins><span class="cx">
</span><span class="cx"> if (!renderTreePosition.canInsert(*newRenderer))
</span><span class="cx"> return;
</span><span class="lines">@@ -442,9 +444,9 @@
</span><span class="cx"> renderTreePosition.insert(*newRenderer.leakPtr());
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void attachTextRenderer(Text& textNode, ContainerNode& renderingParentNode, RenderTreePosition& renderTreePosition)
</del><ins>+void attachTextRenderer(Text& textNode, RenderTreePosition& renderTreePosition)
</ins><span class="cx"> {
</span><del>- createTextRendererIfNeeded(textNode, renderingParentNode, renderTreePosition);
</del><ins>+ createTextRendererIfNeeded(textNode, renderTreePosition);
</ins><span class="cx">
</span><span class="cx"> textNode.clearNeedsStyleRecalc();
</span><span class="cx"> }
</span><span class="lines">@@ -459,19 +461,19 @@
</span><span class="cx"> void updateTextRendererAfterContentChange(Text& textNode, unsigned offsetOfReplacedData, unsigned lengthOfReplacedData)
</span><span class="cx"> {
</span><span class="cx"> ContainerNode* renderingParentNode = NodeRenderingTraversal::parent(&textNode);
</span><del>- if (!renderingParentNode)
</del><ins>+ if (!renderingParentNode || !renderingParentNode->renderer())
</ins><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> bool hadRenderer = textNode.renderer();
</span><span class="cx">
</span><span class="cx"> RenderTreePosition renderTreePosition(renderingParentNode->renderer());
</span><del>- resolveTextNode(textNode, *renderingParentNode, renderTreePosition);
</del><ins>+ resolveTextNode(textNode, renderTreePosition);
</ins><span class="cx">
</span><span class="cx"> if (hadRenderer && textNode.renderer())
</span><span class="cx"> textNode.renderer()->setTextWithOffset(textNode.dataImpl(), offsetOfReplacedData, lengthOfReplacedData);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static void attachChildren(ContainerNode& current, ContainerNode& renderingParentNode, RenderTreePosition& renderTreePosition)
</del><ins>+static void attachChildren(ContainerNode& current, RenderStyle* inheritedStyle, RenderTreePosition& renderTreePosition)
</ins><span class="cx"> {
</span><span class="cx"> for (Node* child = current.firstChild(); child; child = child->nextSibling()) {
</span><span class="cx"> ASSERT((!child->renderer() || child->isNamedFlowContentNode()) || current.shadowRoot());
</span><span class="lines">@@ -480,15 +482,15 @@
</span><span class="cx"> continue;
</span><span class="cx"> }
</span><span class="cx"> if (child->isTextNode()) {
</span><del>- attachTextRenderer(*toText(child), renderingParentNode, renderTreePosition);
</del><ins>+ attachTextRenderer(*toText(child), renderTreePosition);
</ins><span class="cx"> continue;
</span><span class="cx"> }
</span><span class="cx"> if (child->isElementNode())
</span><del>- attachRenderTree(*toElement(child), renderingParentNode, renderTreePosition, nullptr);
</del><ins>+ attachRenderTree(*toElement(child), inheritedStyle, renderTreePosition, nullptr);
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static void attachDistributedChildren(InsertionPoint& insertionPoint, ContainerNode& renderingParentNode, RenderTreePosition& renderTreePosition)
</del><ins>+static void attachDistributedChildren(InsertionPoint& insertionPoint, RenderStyle* inheritedStyle, RenderTreePosition& renderTreePosition)
</ins><span class="cx"> {
</span><span class="cx"> if (ShadowRoot* shadowRoot = insertionPoint.containingShadowRoot())
</span><span class="cx"> ContentDistributor::ensureDistribution(shadowRoot);
</span><span class="lines">@@ -499,19 +501,19 @@
</span><span class="cx"> if (current->isTextNode()) {
</span><span class="cx"> if (current->renderer())
</span><span class="cx"> continue;
</span><del>- attachTextRenderer(*toText(current), renderingParentNode, renderTreePosition);
</del><ins>+ attachTextRenderer(*toText(current), renderTreePosition);
</ins><span class="cx"> continue;
</span><span class="cx"> }
</span><span class="cx"> if (current->isElementNode()) {
</span><span class="cx"> Element& currentElement = toElement(*current);
</span><span class="cx"> if (currentElement.renderer())
</span><span class="cx"> detachRenderTree(currentElement);
</span><del>- attachRenderTree(currentElement, renderingParentNode, renderTreePosition, nullptr);
</del><ins>+ attachRenderTree(currentElement, inheritedStyle, renderTreePosition, nullptr);
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> // Use actual children as fallback content.
</span><span class="cx"> if (!insertionPoint.hasDistribution())
</span><del>- attachChildren(insertionPoint, renderingParentNode, renderTreePosition);
</del><ins>+ attachChildren(insertionPoint, inheritedStyle, renderTreePosition);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> static void attachShadowRoot(ShadowRoot& shadowRoot)
</span><span class="lines">@@ -519,7 +521,7 @@
</span><span class="cx"> ASSERT(shadowRoot.hostElement());
</span><span class="cx">
</span><span class="cx"> RenderTreePosition renderTreePosition(shadowRoot.hostElement()->renderer());
</span><del>- attachChildren(shadowRoot, *shadowRoot.hostElement(), renderTreePosition);
</del><ins>+ attachChildren(shadowRoot, shadowRoot.hostElement()->renderStyle(), renderTreePosition);
</ins><span class="cx">
</span><span class="cx"> shadowRoot.clearNeedsStyleRecalc();
</span><span class="cx"> shadowRoot.clearChildNeedsStyleRecalc();
</span><span class="lines">@@ -572,10 +574,10 @@
</span><span class="cx"> return;
</span><span class="cx"> RefPtr<PseudoElement> pseudoElement = PseudoElement::create(current, pseudoId);
</span><span class="cx"> setBeforeOrAfterPseudoElement(current, pseudoElement, pseudoId);
</span><del>- attachRenderTree(*pseudoElement, current, renderTreePosition, nullptr);
</del><ins>+ attachRenderTree(*pseudoElement, current.renderStyle(), renderTreePosition, nullptr);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-static void attachRenderTree(Element& current, ContainerNode& renderingParentNode, RenderTreePosition& renderTreePosition, PassRefPtr<RenderStyle> resolvedStyle)
</del><ins>+static void attachRenderTree(Element& current, RenderStyle* inheritedStyle, RenderTreePosition& renderTreePosition, PassRefPtr<RenderStyle> resolvedStyle)
</ins><span class="cx"> {
</span><span class="cx"> PostResolutionCallbackDisabler callbackDisabler(current.document());
</span><span class="cx"> WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
</span><span class="lines">@@ -583,7 +585,7 @@
</span><span class="cx"> if (current.hasCustomStyleResolveCallbacks())
</span><span class="cx"> current.willAttachRenderers();
</span><span class="cx">
</span><del>- createRendererIfNeeded(current, renderingParentNode, renderTreePosition, resolvedStyle);
</del><ins>+ createRendererIfNeeded(current, inheritedStyle, renderTreePosition, resolvedStyle);
</ins><span class="cx">
</span><span class="cx"> if (current.parentElement() && current.parentElement()->isInCanvasSubtree())
</span><span class="cx"> current.setIsInCanvasSubtree(true);
</span><span class="lines">@@ -600,9 +602,9 @@
</span><span class="cx"> parentPusher.push();
</span><span class="cx">
</span><span class="cx"> if (isInsertionPoint(current))
</span><del>- attachDistributedChildren(toInsertionPoint(current), renderingParentNode, renderTreePosition);
</del><ins>+ attachDistributedChildren(toInsertionPoint(current), inheritedStyle, renderTreePosition);
</ins><span class="cx"> else
</span><del>- attachChildren(current, current, childRenderTreePosition);
</del><ins>+ attachChildren(current, current.renderStyle(), childRenderTreePosition);
</ins><span class="cx">
</span><span class="cx"> current.clearNeedsStyleRecalc();
</span><span class="cx"> current.clearChildNeedsStyleRecalc();
</span><span class="lines">@@ -613,7 +615,7 @@
</span><span class="cx"> attachBeforeOrAfterPseudoElementIfNeeded(current, AFTER, childRenderTreePosition);
</span><span class="cx">
</span><span class="cx"> current.updateFocusAppearanceAfterAttachIfNeeded();
</span><del>-
</del><ins>+
</ins><span class="cx"> if (current.hasCustomStyleResolveCallbacks())
</span><span class="cx"> current.didAttachRenderers();
</span><span class="cx"> }
</span><span class="lines">@@ -712,7 +714,7 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static Change resolveLocal(Element& current, ContainerNode& renderingParentNode, RenderTreePosition& renderTreePosition, Change inheritedChange)
</del><ins>+static Change resolveLocal(Element& current, RenderStyle* inheritedStyle, RenderTreePosition& renderTreePosition, Change inheritedChange)
</ins><span class="cx"> {
</span><span class="cx"> Change localChange = Detach;
</span><span class="cx"> RefPtr<RenderStyle> newStyle;
</span><span class="lines">@@ -720,13 +722,13 @@
</span><span class="cx">
</span><span class="cx"> Document& document = current.document();
</span><span class="cx"> if (currentStyle && current.styleChangeType() != ReconstructRenderTree) {
</span><del>- newStyle = styleForElement(current, renderingParentNode);
</del><ins>+ newStyle = styleForElement(current, inheritedStyle);
</ins><span class="cx"> localChange = determineChange(currentStyle.get(), newStyle.get());
</span><span class="cx"> }
</span><span class="cx"> if (localChange == Detach) {
</span><span class="cx"> if (current.renderer() || current.isNamedFlowContentNode())
</span><span class="cx"> detachRenderTree(current, ReattachDetach);
</span><del>- attachRenderTree(current, renderingParentNode, renderTreePosition, newStyle.release());
</del><ins>+ attachRenderTree(current, inheritedStyle, renderTreePosition, newStyle.release());
</ins><span class="cx"> invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(current);
</span><span class="cx">
</span><span class="cx"> return Detach;
</span><span class="lines">@@ -758,12 +760,12 @@
</span><span class="cx"> return localChange;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void resolveTextNode(Text& text, ContainerNode& renderingParentNode, RenderTreePosition& renderTreePosition)
</del><ins>+void resolveTextNode(Text& text, RenderTreePosition& renderTreePosition)
</ins><span class="cx"> {
</span><span class="cx"> text.clearNeedsStyleRecalc();
</span><span class="cx">
</span><span class="cx"> bool hasRenderer = text.renderer();
</span><del>- bool needsRenderer = textRendererIsNeeded(text, renderingParentNode);
</del><ins>+ bool needsRenderer = textRendererIsNeeded(text, renderTreePosition);
</ins><span class="cx"> if (hasRenderer) {
</span><span class="cx"> if (needsRenderer)
</span><span class="cx"> return;
</span><span class="lines">@@ -773,7 +775,7 @@
</span><span class="cx"> }
</span><span class="cx"> if (!needsRenderer)
</span><span class="cx"> return;
</span><del>- attachTextRenderer(text, renderingParentNode, renderTreePosition);
</del><ins>+ attachTextRenderer(text, renderTreePosition);
</ins><span class="cx"> invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(text);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -785,11 +787,11 @@
</span><span class="cx"> if (child->renderer())
</span><span class="cx"> renderTreePosition.invalidateNextSibling(*child->renderer());
</span><span class="cx"> if (child->isTextNode() && child->needsStyleRecalc()) {
</span><del>- resolveTextNode(*toText(child), host, renderTreePosition);
</del><ins>+ resolveTextNode(*toText(child), renderTreePosition);
</ins><span class="cx"> continue;
</span><span class="cx"> }
</span><span class="cx"> if (child->isElementNode())
</span><del>- resolveTree(*toElement(child), host, renderTreePosition, change);
</del><ins>+ resolveTree(*toElement(child), host.renderStyle(), renderTreePosition, change);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> shadowRoot.clearNeedsStyleRecalc();
</span><span class="lines">@@ -803,7 +805,7 @@
</span><span class="cx"> renderTreePosition.invalidateNextSibling(*existingPseudoElement->renderer());
</span><span class="cx">
</span><span class="cx"> if (needsPseudoElement(current, pseudoId))
</span><del>- resolveTree(*existingPseudoElement, current, renderTreePosition, current.needsStyleRecalc() ? Force : change);
</del><ins>+ resolveTree(*existingPseudoElement, current.renderStyle(), renderTreePosition, current.needsStyleRecalc() ? Force : change);
</ins><span class="cx"> else
</span><span class="cx"> clearBeforeOrAfterPseudoElement(current, pseudoId);
</span><span class="cx"> return;
</span><span class="lines">@@ -863,7 +865,7 @@
</span><span class="cx"> };
</span><span class="cx"> #endif // PLATFORM(IOS)
</span><span class="cx">
</span><del>-void resolveTree(Element& current, ContainerNode& renderingParentNode, RenderTreePosition& renderTreePosition, Change change)
</del><ins>+void resolveTree(Element& current, RenderStyle* inheritedStyle, RenderTreePosition& renderTreePosition, Change change)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(change != Detach);
</span><span class="cx">
</span><span class="lines">@@ -872,7 +874,6 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- bool hasParentStyle = renderingParentNode.renderStyle();
</del><span class="cx"> bool hasDirectAdjacentRules = current.childrenAffectedByDirectAdjacentRules();
</span><span class="cx"> bool hasIndirectAdjacentRules = current.childrenAffectedByForwardPositionalRules();
</span><span class="cx">
</span><span class="lines">@@ -883,8 +884,8 @@
</span><span class="cx"> if (change > NoChange || current.needsStyleRecalc())
</span><span class="cx"> current.resetComputedStyle();
</span><span class="cx">
</span><del>- if (hasParentStyle && (change >= Inherit || current.needsStyleRecalc()))
- change = resolveLocal(current, renderingParentNode, renderTreePosition, change);
</del><ins>+ if (inheritedStyle && (change >= Inherit || current.needsStyleRecalc()))
+ change = resolveLocal(current, inheritedStyle, renderTreePosition, change);
</ins><span class="cx">
</span><span class="cx"> if (change != Detach) {
</span><span class="cx"> StyleResolverParentPusher parentPusher(&current);
</span><span class="lines">@@ -908,7 +909,7 @@
</span><span class="cx"> if (child->renderer())
</span><span class="cx"> childRenderTreePosition.invalidateNextSibling(*child->renderer());
</span><span class="cx"> if (child->isTextNode() && child->needsStyleRecalc()) {
</span><del>- resolveTextNode(*toText(child), current, childRenderTreePosition);
</del><ins>+ resolveTextNode(*toText(child), childRenderTreePosition);
</ins><span class="cx"> continue;
</span><span class="cx"> }
</span><span class="cx"> if (!child->isElementNode())
</span><span class="lines">@@ -919,7 +920,7 @@
</span><span class="cx"> childElement->setNeedsStyleRecalc();
</span><span class="cx"> if (change >= Inherit || childElement->childNeedsStyleRecalc() || childElement->needsStyleRecalc()) {
</span><span class="cx"> parentPusher.push();
</span><del>- resolveTree(*childElement, current, childRenderTreePosition, change);
</del><ins>+ resolveTree(*childElement, current.renderStyle(), childRenderTreePosition, change);
</ins><span class="cx"> }
</span><span class="cx"> forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
</span><span class="cx"> forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
</span><span class="lines">@@ -960,8 +961,8 @@
</span><span class="cx"> return;
</span><span class="cx"> if (change < Inherit && !documentElement->childNeedsStyleRecalc() && !documentElement->needsStyleRecalc())
</span><span class="cx"> return;
</span><del>- RenderTreePosition renderTreePosition(document.renderView());
- resolveTree(*documentElement, document, renderTreePosition, change);
</del><ins>+ RenderTreePosition renderTreePosition(*document.renderView());
+ resolveTree(*documentElement, document.renderStyle(), renderTreePosition, change);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void detachRenderTree(Element& element)
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGAElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGAElement.cpp (172408 => 172409)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGAElement.cpp        2014-08-11 20:24:19 UTC (rev 172408)
+++ trunk/Source/WebCore/svg/SVGAElement.cpp        2014-08-11 20:42:16 UTC (rev 172409)
</span><span class="lines">@@ -248,9 +248,10 @@
</span><span class="cx"> // The 'a' element may contain any element that its parent may contain, except itself.
</span><span class="cx"> if (child.hasTagName(SVGNames::aTag))
</span><span class="cx"> return false;
</span><del>- if (parentNode() && parentNode()->isSVGElement())
- return parentNode()->childShouldCreateRenderer(child);
</del><span class="cx">
</span><ins>+ if (parentElement() && parentElement()->isSVGElement())
+ return parentElement()->childShouldCreateRenderer(child);
+
</ins><span class="cx"> return SVGElement::childShouldCreateRenderer(child);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGDocument.cpp (172408 => 172409)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGDocument.cpp        2014-08-11 20:24:19 UTC (rev 172408)
+++ trunk/Source/WebCore/svg/SVGDocument.cpp        2014-08-11 20:42:16 UTC (rev 172409)
</span><span class="lines">@@ -76,13 +76,6 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool SVGDocument::childShouldCreateRenderer(const Node& child) const
-{
- if (isSVGSVGElement(child))
- return toSVGSVGElement(child).isValid();
- return true;
-}
-
</del><span class="cx"> PassRefPtr<Document> SVGDocument::cloneDocumentWithoutChildren() const
</span><span class="cx"> {
</span><span class="cx"> return create(nullptr, url());
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGDocument.h (172408 => 172409)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGDocument.h        2014-08-11 20:24:19 UTC (rev 172408)
+++ trunk/Source/WebCore/svg/SVGDocument.h        2014-08-11 20:42:16 UTC (rev 172409)
</span><span class="lines">@@ -47,8 +47,6 @@
</span><span class="cx"> private:
</span><span class="cx"> SVGDocument(Frame*, const URL&);
</span><span class="cx">
</span><del>- virtual bool childShouldCreateRenderer(const Node&) const override;
-
</del><span class="cx"> virtual PassRefPtr<Document> cloneDocumentWithoutChildren() const override;
</span><span class="cx">
</span><span class="cx"> FloatPoint m_translate;
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGSVGElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGSVGElement.cpp (172408 => 172409)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGSVGElement.cpp        2014-08-11 20:24:19 UTC (rev 172408)
+++ trunk/Source/WebCore/svg/SVGSVGElement.cpp        2014-08-11 20:42:16 UTC (rev 172409)
</span><span class="lines">@@ -459,6 +459,8 @@
</span><span class="cx">
</span><span class="cx"> bool SVGSVGElement::rendererIsNeeded(const RenderStyle& style)
</span><span class="cx"> {
</span><ins>+ if (!isValid())
+ return false;
</ins><span class="cx"> // FIXME: We should respect display: none on the documentElement svg element
</span><span class="cx"> // but many things in FrameView and SVGImage depend on the RenderSVGRoot when
</span><span class="cx"> // they should instead depend on the RenderView.
</span></span></pre>
</div>
</div>
</body>
</html>