diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/html/HTMLDetailsElement.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebCore/html/HTMLDetailsElement.cpp')
-rw-r--r-- | Source/WebCore/html/HTMLDetailsElement.cpp | 151 |
1 files changed, 59 insertions, 92 deletions
diff --git a/Source/WebCore/html/HTMLDetailsElement.cpp b/Source/WebCore/html/HTMLDetailsElement.cpp index ba529d90c..e8bdf3066 100644 --- a/Source/WebCore/html/HTMLDetailsElement.cpp +++ b/Source/WebCore/html/HTMLDetailsElement.cpp @@ -22,115 +22,94 @@ #include "HTMLDetailsElement.h" #if ENABLE(DETAILS_ELEMENT) -#include "HTMLContentElement.h" -#include "HTMLNames.h" +#include "AXObjectCache.h" +#include "ElementIterator.h" +#include "HTMLSlotElement.h" #include "HTMLSummaryElement.h" #include "LocalizedStrings.h" #include "MouseEvent.h" -#include "NodeRenderingContext.h" -#include "RenderBlock.h" +#include "RenderBlockFlow.h" #include "ShadowRoot.h" +#include "SlotAssignment.h" #include "Text.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { using namespace HTMLNames; -static const AtomicString& summaryQuerySelector() +static const AtomicString& summarySlotName() { - DEFINE_STATIC_LOCAL(AtomicString, selector, ("summary:first-of-type", AtomicString::ConstructFromLiteral)); - return selector; -}; - -class DetailsContentElement : public InsertionPoint { -public: - static PassRefPtr<DetailsContentElement> create(Document*); - -private: - DetailsContentElement(Document* document) - : InsertionPoint(HTMLNames::webkitShadowContentTag, document) - { - } - - virtual MatchType matchTypeFor(Node* node) const OVERRIDE - { - if (node->isElementNode() && node == node->parentNode()->querySelector(summaryQuerySelector(), ASSERT_NO_EXCEPTION)) - return NeverMatches; - return AlwaysMatches; - } -}; - -PassRefPtr<DetailsContentElement> DetailsContentElement::create(Document* document) -{ - return adoptRef(new DetailsContentElement(document)); + static NeverDestroyed<AtomicString> summarySlot("summarySlot"); + return summarySlot; } -class DetailsSummaryElement : public InsertionPoint { -public: - static PassRefPtr<DetailsSummaryElement> create(Document*); - - Element* fallbackSummary() - { - ASSERT(firstChild() && firstChild()->hasTagName(summaryTag)); - return toElement(firstChild()); +static AtomicString slotNameFunction(const Node& child) +{ + auto& parent = *child.parentNode(); + ASSERT(is<HTMLDetailsElement>(parent)); + auto& details = downcast<HTMLDetailsElement>(parent); + + // The first summary child gets assigned to the summary slot. + if (is<HTMLSummaryElement>(child)) { + if (&child == childrenOfType<HTMLSummaryElement>(details).first()) + return summarySlotName(); } + // Everything else is assigned to the default slot if details is open. + if (details.isOpen()) + return SlotAssignment::defaultSlotName(); -private: - DetailsSummaryElement(Document* document) - : InsertionPoint(HTMLNames::webkitShadowContentTag, document) - { } - - virtual MatchType matchTypeFor(Node* node) const OVERRIDE - { - if (node->isElementNode() && node == node->parentNode()->querySelector(summaryQuerySelector(), ASSERT_NO_EXCEPTION)) - return AlwaysMatches; - return NeverMatches; - } + // Otherwise don't render the content. + return nullAtom; }; -PassRefPtr<DetailsSummaryElement> DetailsSummaryElement::create(Document* document) -{ - RefPtr<HTMLSummaryElement> summary = HTMLSummaryElement::create(summaryTag, document); - summary->appendChild(Text::create(document, defaultDetailsSummaryText()), ASSERT_NO_EXCEPTION); - - RefPtr<DetailsSummaryElement> detailsSummary = adoptRef(new DetailsSummaryElement(document)); - detailsSummary->appendChild(summary); - return detailsSummary.release(); -} - -PassRefPtr<HTMLDetailsElement> HTMLDetailsElement::create(const QualifiedName& tagName, Document* document) +Ref<HTMLDetailsElement> HTMLDetailsElement::create(const QualifiedName& tagName, Document& document) { - RefPtr<HTMLDetailsElement> details = adoptRef(new HTMLDetailsElement(tagName, document)); - details->ensureUserAgentShadowRoot(); - return details.release(); + auto details = adoptRef(*new HTMLDetailsElement(tagName, document)); + details->addShadowRoot(ShadowRoot::create(document, std::make_unique<SlotAssignment>(slotNameFunction))); + return details; } -HTMLDetailsElement::HTMLDetailsElement(const QualifiedName& tagName, Document* document) +HTMLDetailsElement::HTMLDetailsElement(const QualifiedName& tagName, Document& document) : HTMLElement(tagName, document) - , m_isOpen(false) { ASSERT(hasTagName(detailsTag)); } -RenderObject* HTMLDetailsElement::createRenderer(RenderArena* arena, RenderStyle*) +RenderPtr<RenderElement> HTMLDetailsElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&) { - return new (arena) RenderBlock(this); + return createRenderer<RenderBlockFlow>(*this, WTFMove(style)); } void HTMLDetailsElement::didAddUserAgentShadowRoot(ShadowRoot* root) { - root->appendChild(DetailsSummaryElement::create(document()), ASSERT_NO_EXCEPTION, AttachLazily); - root->appendChild(DetailsContentElement::create(document()), ASSERT_NO_EXCEPTION, AttachLazily); + auto summarySlot = HTMLSlotElement::create(slotTag, document()); + summarySlot->setAttribute(nameAttr, summarySlotName()); + m_summarySlot = summarySlot.ptr(); + + auto defaultSummary = HTMLSummaryElement::create(summaryTag, document()); + defaultSummary->appendChild(Text::create(document(), defaultDetailsSummaryText()), ASSERT_NO_EXCEPTION); + m_defaultSummary = defaultSummary.ptr(); + + summarySlot->appendChild(WTFMove(defaultSummary)); + root->appendChild(WTFMove(summarySlot)); + + auto defaultSlot = HTMLSlotElement::create(slotTag, document()); + root->appendChild(WTFMove(defaultSlot)); } -Element* HTMLDetailsElement::findMainSummary() const +bool HTMLDetailsElement::isActiveSummary(const HTMLSummaryElement& summary) const { - for (Node* child = firstChild(); child; child = child->nextSibling()) { - if (child->hasTagName(summaryTag)) - return toElement(child); - } + if (!m_summarySlot->assignedNodes()) + return &summary == m_defaultSummary; - return static_cast<DetailsSummaryElement*>(userAgentShadowRoot()->firstChild())->fallbackSummary(); + if (summary.parentNode() != this) + return false; + + auto* slot = shadowRoot()->findAssignedSlot(summary); + if (!slot) + return false; + return slot == m_summarySlot; } void HTMLDetailsElement::parseAttribute(const QualifiedName& name, const AtomicString& value) @@ -139,31 +118,19 @@ void HTMLDetailsElement::parseAttribute(const QualifiedName& name, const AtomicS bool oldValue = m_isOpen; m_isOpen = !value.isNull(); if (oldValue != m_isOpen) - reattachIfAttached(); + shadowRoot()->invalidateSlotAssignments(); } else HTMLElement::parseAttribute(name, value); } -bool HTMLDetailsElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const -{ - if (childContext.node()->isPseudoElement()) - return HTMLElement::childShouldCreateRenderer(childContext); - - if (!childContext.isOnEncapsulationBoundary()) - return false; - - if (m_isOpen) - return HTMLElement::childShouldCreateRenderer(childContext); - - if (!childContext.node()->hasTagName(summaryTag)) - return false; - - return childContext.node() == findMainSummary() && HTMLElement::childShouldCreateRenderer(childContext); -} void HTMLDetailsElement::toggleOpen() { setAttribute(openAttr, m_isOpen ? nullAtom : emptyAtom); + + // We need to post to the document because toggling this element will delete it. + if (AXObjectCache* cache = document().existingAXObjectCache()) + cache->postNotification(nullptr, &document(), AXObjectCache::AXExpandedChanged); } } |