summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/html/HTMLDetailsElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/HTMLDetailsElement.cpp')
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.cpp112
1 files changed, 62 insertions, 50 deletions
diff --git a/Source/WebCore/html/HTMLDetailsElement.cpp b/Source/WebCore/html/HTMLDetailsElement.cpp
index f9c2f6c..b41f5dd 100644
--- a/Source/WebCore/html/HTMLDetailsElement.cpp
+++ b/Source/WebCore/html/HTMLDetailsElement.cpp
@@ -21,11 +21,12 @@
#include "config.h"
#include "HTMLDetailsElement.h"
-#include "Frame.h"
#include "HTMLNames.h"
+#include "HTMLSummaryElement.h"
+#include "LocalizedStrings.h"
#include "MouseEvent.h"
-#include "PlatformMouseEvent.h"
#include "RenderDetails.h"
+#include "Text.h"
namespace WebCore {
@@ -49,48 +50,76 @@ RenderObject* HTMLDetailsElement::createRenderer(RenderArena* arena, RenderStyle
return new (arena) RenderDetails(this);
}
-void HTMLDetailsElement::findMainSummary()
+Node* HTMLDetailsElement::findSummaryFor(ContainerNode* container)
{
- m_mainSummary = 0;
+ for (Node* child = container->firstChild(); child; child = child->nextSibling()) {
+ if (child->hasTagName(summaryTag))
+ return child;
+ }
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(summaryTag)) {
- m_mainSummary = child;
- break;
- }
+ return 0;
+}
+
+Node* HTMLDetailsElement::findMainSummary()
+{
+ Node* found = findSummaryFor(this);
+ if (found) {
+ removeShadowRoot();
+ return found;
}
+
+ createShadowSubtree();
+ found = findSummaryFor(shadowRoot());
+ ASSERT(found);
+ return found;
+}
+
+void HTMLDetailsElement::refreshMainSummary(RefreshRenderer refreshRenderer)
+{
+ RefPtr<Node> oldSummary = m_mainSummary;
+ m_mainSummary = findMainSummary();
+
+ if (oldSummary == m_mainSummary || !attached())
+ return;
+
+ if (oldSummary && oldSummary->parentNodeForRenderingAndStyle()) {
+ oldSummary->detach();
+ oldSummary->attach();
+ }
+
+ if (refreshRenderer == RefreshRendererAllowed) {
+ m_mainSummary->detach();
+ m_mainSummary->attach();
+ }
+}
+
+void HTMLDetailsElement::createShadowSubtree()
+{
+ if (shadowRoot())
+ return;
+
+ RefPtr<HTMLSummaryElement> defaultSummary = HTMLSummaryElement::create(summaryTag, document());
+ ExceptionCode ec = 0;
+ defaultSummary->appendChild(Text::create(document(), defaultDetailsSummaryText()), ec);
+ ensureShadowRoot()->appendChild(defaultSummary, ec, true);
}
+
void HTMLDetailsElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!changedByParser) {
- Node* oldSummary = m_mainSummary;
- findMainSummary();
-
- if (oldSummary != m_mainSummary && !m_isOpen && attached()) {
- if (oldSummary && oldSummary->attached())
- oldSummary->detach();
- if (m_mainSummary && childCountDelta < 0 && !m_mainSummary->renderer()) {
- // If childCountDelta is less then zero and the main summary has changed it must be because previous main
- // summary was removed. The new main summary was then inside the unrevealed content and needs to be
- // reattached to create its renderer. If childCountDelta is not less then zero then a new <summary> element
- // has been added and it will be attached without our help.
- m_mainSummary->detach();
- m_mainSummary->attach();
- }
- }
- }
+ // If childCountDelta is less then zero and the main summary has changed it must be because previous main
+ // summary was removed. The new main summary was then inside the unrevealed content and needs to be
+ // reattached to create its renderer. If childCountDelta is not less then zero then a new <summary> element
+ // has been added and it will be attached without our help.
+ if (!changedByParser)
+ refreshMainSummary(childCountDelta < 0 ? RefreshRendererAllowed : RefreshRendererSupressed);
}
void HTMLDetailsElement::finishParsingChildren()
{
HTMLElement::finishParsingChildren();
- findMainSummary();
- if (attached() && m_mainSummary && !m_mainSummary->renderer()) {
- m_mainSummary->detach();
- m_mainSummary->attach();
- }
+ refreshMainSummary(RefreshRendererAllowed);
}
void HTMLDetailsElement::parseMappedAttribute(Attribute* attr)
@@ -111,26 +140,9 @@ bool HTMLDetailsElement::childShouldCreateRenderer(Node* child) const
return m_isOpen || child == m_mainSummary;
}
-void HTMLDetailsElement::defaultEventHandler(Event* event)
+void HTMLDetailsElement::toggleOpen()
{
- HTMLElement::defaultEventHandler(event);
-
- if (!renderer() || !renderer()->isDetails() || !event->isMouseEvent() || event->type() != eventNames().clickEvent || event->defaultHandled())
- return;
-
- MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
- if (mouseEvent->button() != LeftButton)
- return;
-
- RenderDetails* renderDetails = static_cast<RenderDetails*>(renderer());
-
- float factor = document() && document()->frame() ? document()->frame()->pageZoomFactor() : 1.0f;
- FloatPoint pos = renderDetails->absoluteToLocal(FloatPoint(mouseEvent->pageX() * factor, mouseEvent->pageY() * factor));
-
- if (renderDetails->interactiveArea().contains(pos.x(), pos.y())) {
- setAttribute(openAttr, m_isOpen ? String() : String(""));
- event->setDefaultHandled();
- }
+ setAttribute(openAttr, m_isOpen ? nullAtom : emptyAtom);
}
}