Bug 591737 - Implement toggling open details by mouse click. r=bz

This commit is contained in:
Ting-Yu Lin 2016-01-20 23:20:42 +08:00
parent 2304f68a95
commit 5b26d8aa11
3 changed files with 51 additions and 0 deletions

View File

@ -45,6 +45,13 @@ public:
SetHTMLBoolAttr(nsGkAtoms::open, aOpen, aError);
}
void ToggleOpen()
{
ErrorResult rv;
SetOpen(!Open(), rv);
rv.SuppressException();
}
protected:
virtual ~HTMLDetailsElement();

View File

@ -7,6 +7,7 @@
#include "mozilla/dom/HTMLDetailsElement.h"
#include "mozilla/dom/HTMLElementBinding.h"
#include "mozilla/MouseEvents.h"
NS_IMPL_NS_NEW_HTML_ELEMENT(Summary)
@ -19,6 +20,46 @@ HTMLSummaryElement::~HTMLSummaryElement()
NS_IMPL_ELEMENT_CLONE(HTMLSummaryElement)
nsresult
HTMLSummaryElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
{
nsresult rv = NS_OK;
if (!aVisitor.mPresContext) {
return rv;
}
if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault) {
return rv;
}
auto toggleDetails = false;
auto* event = aVisitor.mEvent;
if (event->HasMouseEventMessage()) {
auto* mouseEvent = event->AsMouseEvent();
toggleDetails = mouseEvent->IsLeftClickEvent();
}
// Todo: Bug 634004: Implement toggle details by keyboard.
if (!toggleDetails || !IsMainSummary()) {
return rv;
}
auto* details = GetDetails();
MOZ_ASSERT(details, "Expected to find details since this is the main summary!");
// When dispatching a synthesized mouse click event to a details with
// 'display: none', both Chrome and Safari do not toggle the 'open' attribute.
// We follow them by checking whether details has a frame or not.
if (details->GetPrimaryFrame()) {
details->ToggleOpen();
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
}
return rv;
}
bool
HTMLSummaryElement::IsMainSummary() const
{

View File

@ -11,6 +11,7 @@
namespace mozilla {
namespace dom {
class HTMLDetailsElement;
// HTMLSummaryElement implements the <summary> tag, which is used as a summary
// or legend of the <details> tag. Please see the spec for more information.
@ -30,6 +31,8 @@ public:
nsresult Clone(NodeInfo* aNodeInfo, nsINode** aResult) const override;
nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
// Return true if this is the first summary element child of a details or the
// default summary element generated by DetailsFrame.
bool IsMainSummary() const;