mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1225412 Part 2 - Add support to dispatch toggle events to details element. r=smaug
Add ontoggle event handler, and dispatch toggle events to the details element if the open attribute is added or changed. According to the spec, if a new toggle event has been queued, previous toggle events should be aborted. MozReview-Commit-ID: EN6Jf5hVHHD --HG-- extra : rebase_source : 35605e49950bb59a0eb6dca594c3ede465ff587d
This commit is contained in:
parent
e112dca692
commit
b8972c7eb9
@ -923,6 +923,7 @@ GK_ATOM(onsubmit, "onsubmit")
|
||||
GK_ATOM(onsuccess, "onsuccess")
|
||||
GK_ATOM(ontypechange, "ontypechange")
|
||||
GK_ATOM(ontext, "ontext")
|
||||
GK_ATOM(ontoggle, "ontoggle")
|
||||
GK_ATOM(ontouchstart, "ontouchstart")
|
||||
GK_ATOM(ontouchend, "ontouchend")
|
||||
GK_ATOM(ontouchmove, "ontouchmove")
|
||||
|
@ -421,6 +421,10 @@ EVENT(timeupdate,
|
||||
eTimeUpdate,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(toggle,
|
||||
eToggle,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(volumechange,
|
||||
eVolumeChange,
|
||||
EventNameType_HTML,
|
||||
|
@ -71,6 +71,25 @@ HTMLDetailsElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
return hint;
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLDetailsElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
nsAttrValueOrString* aValue, bool aNotify)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::open) {
|
||||
bool setOpen = aValue != nullptr;
|
||||
if (Open() != setOpen) {
|
||||
if (mToggleEventDispatcher) {
|
||||
mToggleEventDispatcher->Cancel();
|
||||
}
|
||||
mToggleEventDispatcher = new ToggleEventDispatcher(this);
|
||||
mToggleEventDispatcher->PostDOMEvent();
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::BeforeSetAttr(aNameSpaceID, aName, aValue,
|
||||
aNotify);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
HTMLDetailsElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef mozilla_dom_HTMLDetailsElement_h
|
||||
#define mozilla_dom_HTMLDetailsElement_h
|
||||
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
|
||||
@ -38,12 +39,14 @@ public:
|
||||
nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
int32_t aModType) const override;
|
||||
|
||||
nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
nsAttrValueOrString* aValue, bool aNotify) override;
|
||||
|
||||
// HTMLDetailsElement WebIDL
|
||||
bool Open() const { return GetBoolAttr(nsGkAtoms::open); }
|
||||
|
||||
void SetOpen(bool aOpen, ErrorResult& aError)
|
||||
{
|
||||
// TODO: Bug 1225412: Need to follow the spec to fire "toggle" event.
|
||||
SetHTMLBoolAttr(nsGkAtoms::open, aOpen, aError);
|
||||
}
|
||||
|
||||
@ -59,6 +62,26 @@ protected:
|
||||
|
||||
JSObject* WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
class ToggleEventDispatcher final : public AsyncEventDispatcher
|
||||
{
|
||||
public:
|
||||
// According to the html spec, a 'toggle' event is a simple event which does
|
||||
// not bubble.
|
||||
explicit ToggleEventDispatcher(nsINode* aTarget)
|
||||
: AsyncEventDispatcher(aTarget, NS_LITERAL_STRING("toggle"), false)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
auto* details = static_cast<HTMLDetailsElement*>(mTarget.get());
|
||||
details->mToggleEventDispatcher = nullptr;
|
||||
return AsyncEventDispatcher::Run();
|
||||
}
|
||||
};
|
||||
|
||||
RefPtr<ToggleEventDispatcher> mToggleEventDispatcher;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -92,6 +92,9 @@ interface GlobalEventHandlers {
|
||||
[Pref="dom.select_events.enabled"]
|
||||
attribute EventHandler onselectstart;
|
||||
|
||||
[Pref="dom.details_element.enabled"]
|
||||
attribute EventHandler ontoggle;
|
||||
|
||||
// Pointer events handlers
|
||||
[Pref="dom.w3c_pointer_events.enabled"]
|
||||
attribute EventHandler onpointercancel;
|
||||
|
@ -136,9 +136,6 @@
|
||||
[Document interface: attribute onsort]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: attribute ontoggle]
|
||||
expected: FAIL
|
||||
|
||||
[Stringification of iframe.contentDocument]
|
||||
expected: FAIL
|
||||
|
||||
@ -205,9 +202,6 @@
|
||||
[Document interface: iframe.contentDocument must inherit property "onsort" with the proper type (148)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: iframe.contentDocument must inherit property "ontoggle" with the proper type (153)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "origin" with the proper type (3)]
|
||||
expected: FAIL
|
||||
|
||||
@ -409,9 +403,6 @@
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onsort" with the proper type (148)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "ontoggle" with the proper type (153)]
|
||||
expected: FAIL
|
||||
|
||||
[Touch interface: attribute region]
|
||||
expected: FAIL
|
||||
|
||||
@ -592,9 +583,6 @@
|
||||
[HTMLElement interface: attribute onsort]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: attribute ontoggle]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: document.createElement("noscript") must inherit property "translate" with the proper type (2)]
|
||||
expected: FAIL
|
||||
|
||||
@ -646,9 +634,6 @@
|
||||
[HTMLElement interface: document.createElement("noscript") must inherit property "onsort" with the proper type (87)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: document.createElement("noscript") must inherit property "ontoggle" with the proper type (92)]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: document.createElement("noscript") must inherit property "prepend" with the proper type (31)]
|
||||
expected: FAIL
|
||||
|
||||
@ -1965,9 +1950,6 @@
|
||||
[Window interface: attribute onsort]
|
||||
expected: FAIL
|
||||
|
||||
[Window interface: attribute ontoggle]
|
||||
expected: FAIL
|
||||
|
||||
[Window interface: operation createImageBitmap(ImageBitmapSource,long,long,long,long)]
|
||||
expected: FAIL
|
||||
|
||||
@ -2000,9 +1982,6 @@
|
||||
[Window interface: window must inherit property "onsort" with the proper type (93)]
|
||||
expected: FAIL
|
||||
|
||||
[Window interface: window must inherit property "ontoggle" with the proper type (98)]
|
||||
expected: FAIL
|
||||
|
||||
[Window interface: calling showModalDialog(DOMString,any) on window with too few arguments must throw TypeError]
|
||||
expected:
|
||||
if not e10s: PASS
|
||||
@ -2515,9 +2494,6 @@
|
||||
[Document interface: iframe.contentDocument must inherit property "onsort" with the proper type (149)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: iframe.contentDocument must inherit property "ontoggle" with the proper type (154)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "styleSheetSets" with the proper type (32)]
|
||||
expected: FAIL
|
||||
|
||||
@ -2665,9 +2641,6 @@
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onsort" with the proper type (149)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "ontoggle" with the proper type (154)]
|
||||
expected: FAIL
|
||||
|
||||
[Location interface: window.location must have own property "ancestorOrigins"]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -1,21 +1,3 @@
|
||||
[toggleEvent.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[Adding open to 'details' should fire a toggle event at the 'details' element]
|
||||
expected: NOTRUN
|
||||
|
||||
[Removing open from 'details' should fire a toggle event at the 'details' element]
|
||||
expected: NOTRUN
|
||||
|
||||
[Adding open to 'details' (display:none) should fire a toggle event at the 'details' element]
|
||||
expected: NOTRUN
|
||||
|
||||
[Adding open from 'details' (no children) should fire a toggle event at the 'details' element]
|
||||
expected: NOTRUN
|
||||
|
||||
[Calling open twice on 'details' fires only one toggle event]
|
||||
expected: FAIL
|
||||
|
||||
[Adding open to 'details' (not in the document) should fire a toggle event at the 'details' element]
|
||||
expected: TIMEOUT
|
||||
|
||||
prefs: [dom.details_element.enabled:true]
|
||||
|
@ -24,17 +24,42 @@
|
||||
<summary>Lorem ipsum</summary>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
||||
</details>
|
||||
<details id=details7>
|
||||
<summary>Lorem ipsum</summary>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
||||
</details>
|
||||
<details id=details8 open>
|
||||
<summary>Lorem ipsum</summary>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
||||
</details>
|
||||
<details id=details9 open>
|
||||
<summary>Lorem ipsum</summary>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
||||
</details>
|
||||
<details id=details10>
|
||||
<summary>Lorem ipsum</summary>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
||||
</details>
|
||||
<script>
|
||||
var t1 = async_test("Adding open to 'details' should fire a toggle event at the 'details' element"),
|
||||
t2 = async_test("Removing open from 'details' should fire a toggle event at the 'details' element"),
|
||||
t3 = async_test("Adding open to 'details' (display:none) should fire a toggle event at the 'details' element"),
|
||||
t4 = async_test("Adding open from 'details' (no children) should fire a toggle event at the 'details' element"),
|
||||
t6 = async_test("Calling open twice on 'details' fires only one toggle event"),
|
||||
t7 = async_test("Calling setAttribute('open', '') to 'details' should fire a toggle event at the 'details' element"),
|
||||
t8 = async_test("Calling removeAttribute('open') to 'details' should fire a toggle event at the 'details' element"),
|
||||
t9 = async_test("Setting open=true to opened 'details' element should not fire a toggle event at the 'details' element"),
|
||||
t10 = async_test("Setting open=false to closed 'details' element should not fire a toggle event at the 'details' element"),
|
||||
|
||||
details1 = document.getElementById('details1'),
|
||||
details2 = document.getElementById('details2'),
|
||||
details3 = document.getElementById('details3'),
|
||||
details4 = document.getElementById('details4'),
|
||||
details6 = document.getElementById('details6'),
|
||||
details7 = document.getElementById('details7'),
|
||||
details8 = document.getElementById('details8'),
|
||||
details9 = document.getElementById('details9'),
|
||||
details10 = document.getElementById('details10'),
|
||||
loop=false;
|
||||
|
||||
function testEvent(evt) {
|
||||
@ -90,4 +115,43 @@
|
||||
assert_true(loop);
|
||||
t6.done();
|
||||
}), 0);
|
||||
|
||||
details7.ontoggle = t7.step_func_done(function(evt) {
|
||||
assert_true(details7.open);
|
||||
testEvent(evt)
|
||||
});
|
||||
details7.setAttribute('open', ''); // opens details7
|
||||
|
||||
details8.ontoggle = t8.step_func_done(function(evt) {
|
||||
assert_false(details8.open);
|
||||
testEvent(evt)
|
||||
});
|
||||
details8.removeAttribute('open'); // closes details8
|
||||
|
||||
var toggleFiredOnDetails9 = false;
|
||||
details9.ontoggle = t9.step_func_done(function(evt) {
|
||||
if (toggleFiredOnDetails9) {
|
||||
assert_unreached("toggle event fired twice on opened details element");
|
||||
} else {
|
||||
toggleFiredOnDetails9 = true;
|
||||
}
|
||||
});
|
||||
// The toggle event should be fired once when declaring details9 with open
|
||||
// attribute.
|
||||
details9.open = true; // opens details9
|
||||
setTimeout(t9.step_func(function() {
|
||||
assert_true(details9.open);
|
||||
assert_true(toggleFiredOnDetails9);
|
||||
t9.done();
|
||||
}), 0);
|
||||
|
||||
details10.ontoggle = t10.step_func_done(function(evt) {
|
||||
assert_unreached("toggle event fired on closed details element");
|
||||
});
|
||||
details10.open = false;
|
||||
setTimeout(t10.step_func(function() {
|
||||
assert_false(details10.open);
|
||||
t10.done();
|
||||
}), 0);
|
||||
|
||||
</script>
|
||||
|
@ -415,6 +415,9 @@ NS_EVENT_MESSAGE(eEditorInput)
|
||||
NS_EVENT_MESSAGE(eSelectStart)
|
||||
NS_EVENT_MESSAGE(eSelectionChange)
|
||||
|
||||
// Details element events.
|
||||
NS_EVENT_MESSAGE(eToggle)
|
||||
|
||||
#ifdef UNDEF_NS_EVENT_MESSAGE_FIRST_LAST
|
||||
#undef UNDEF_NS_EVENT_MESSAGE_FIRST_LAST
|
||||
#undef NS_EVENT_MESSAGE_FIRST_LAST
|
||||
|
Loading…
Reference in New Issue
Block a user