mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +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(onsuccess, "onsuccess")
|
||||||
GK_ATOM(ontypechange, "ontypechange")
|
GK_ATOM(ontypechange, "ontypechange")
|
||||||
GK_ATOM(ontext, "ontext")
|
GK_ATOM(ontext, "ontext")
|
||||||
|
GK_ATOM(ontoggle, "ontoggle")
|
||||||
GK_ATOM(ontouchstart, "ontouchstart")
|
GK_ATOM(ontouchstart, "ontouchstart")
|
||||||
GK_ATOM(ontouchend, "ontouchend")
|
GK_ATOM(ontouchend, "ontouchend")
|
||||||
GK_ATOM(ontouchmove, "ontouchmove")
|
GK_ATOM(ontouchmove, "ontouchmove")
|
||||||
|
@ -421,6 +421,10 @@ EVENT(timeupdate,
|
|||||||
eTimeUpdate,
|
eTimeUpdate,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
|
EVENT(toggle,
|
||||||
|
eToggle,
|
||||||
|
EventNameType_HTML,
|
||||||
|
eBasicEventClass)
|
||||||
EVENT(volumechange,
|
EVENT(volumechange,
|
||||||
eVolumeChange,
|
eVolumeChange,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
|
@ -71,6 +71,25 @@ HTMLDetailsElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
|||||||
return hint;
|
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*
|
JSObject*
|
||||||
HTMLDetailsElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
HTMLDetailsElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#ifndef mozilla_dom_HTMLDetailsElement_h
|
#ifndef mozilla_dom_HTMLDetailsElement_h
|
||||||
#define mozilla_dom_HTMLDetailsElement_h
|
#define mozilla_dom_HTMLDetailsElement_h
|
||||||
|
|
||||||
|
#include "mozilla/AsyncEventDispatcher.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "nsGenericHTMLElement.h"
|
#include "nsGenericHTMLElement.h"
|
||||||
|
|
||||||
@ -38,12 +39,14 @@ public:
|
|||||||
nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||||
int32_t aModType) const override;
|
int32_t aModType) const override;
|
||||||
|
|
||||||
|
nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
|
nsAttrValueOrString* aValue, bool aNotify) override;
|
||||||
|
|
||||||
// HTMLDetailsElement WebIDL
|
// HTMLDetailsElement WebIDL
|
||||||
bool Open() const { return GetBoolAttr(nsGkAtoms::open); }
|
bool Open() const { return GetBoolAttr(nsGkAtoms::open); }
|
||||||
|
|
||||||
void SetOpen(bool aOpen, ErrorResult& aError)
|
void SetOpen(bool aOpen, ErrorResult& aError)
|
||||||
{
|
{
|
||||||
// TODO: Bug 1225412: Need to follow the spec to fire "toggle" event.
|
|
||||||
SetHTMLBoolAttr(nsGkAtoms::open, aOpen, aError);
|
SetHTMLBoolAttr(nsGkAtoms::open, aOpen, aError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +62,26 @@ protected:
|
|||||||
|
|
||||||
JSObject* WrapNode(JSContext* aCx,
|
JSObject* WrapNode(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aGivenProto) override;
|
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
|
} // namespace dom
|
||||||
|
@ -92,6 +92,9 @@ interface GlobalEventHandlers {
|
|||||||
[Pref="dom.select_events.enabled"]
|
[Pref="dom.select_events.enabled"]
|
||||||
attribute EventHandler onselectstart;
|
attribute EventHandler onselectstart;
|
||||||
|
|
||||||
|
[Pref="dom.details_element.enabled"]
|
||||||
|
attribute EventHandler ontoggle;
|
||||||
|
|
||||||
// Pointer events handlers
|
// Pointer events handlers
|
||||||
[Pref="dom.w3c_pointer_events.enabled"]
|
[Pref="dom.w3c_pointer_events.enabled"]
|
||||||
attribute EventHandler onpointercancel;
|
attribute EventHandler onpointercancel;
|
||||||
|
@ -136,9 +136,6 @@
|
|||||||
[Document interface: attribute onsort]
|
[Document interface: attribute onsort]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Document interface: attribute ontoggle]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Stringification of iframe.contentDocument]
|
[Stringification of iframe.contentDocument]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@ -205,9 +202,6 @@
|
|||||||
[Document interface: iframe.contentDocument must inherit property "onsort" with the proper type (148)]
|
[Document interface: iframe.contentDocument must inherit property "onsort" with the proper type (148)]
|
||||||
expected: FAIL
|
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)]
|
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "origin" with the proper type (3)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@ -409,9 +403,6 @@
|
|||||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onsort" with the proper type (148)]
|
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onsort" with the proper type (148)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "ontoggle" with the proper type (153)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Touch interface: attribute region]
|
[Touch interface: attribute region]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@ -592,9 +583,6 @@
|
|||||||
[HTMLElement interface: attribute onsort]
|
[HTMLElement interface: attribute onsort]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[HTMLElement interface: attribute ontoggle]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[HTMLElement interface: document.createElement("noscript") must inherit property "translate" with the proper type (2)]
|
[HTMLElement interface: document.createElement("noscript") must inherit property "translate" with the proper type (2)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@ -646,9 +634,6 @@
|
|||||||
[HTMLElement interface: document.createElement("noscript") must inherit property "onsort" with the proper type (87)]
|
[HTMLElement interface: document.createElement("noscript") must inherit property "onsort" with the proper type (87)]
|
||||||
expected: FAIL
|
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)]
|
[Element interface: document.createElement("noscript") must inherit property "prepend" with the proper type (31)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@ -1965,9 +1950,6 @@
|
|||||||
[Window interface: attribute onsort]
|
[Window interface: attribute onsort]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Window interface: attribute ontoggle]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Window interface: operation createImageBitmap(ImageBitmapSource,long,long,long,long)]
|
[Window interface: operation createImageBitmap(ImageBitmapSource,long,long,long,long)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@ -2000,9 +1982,6 @@
|
|||||||
[Window interface: window must inherit property "onsort" with the proper type (93)]
|
[Window interface: window must inherit property "onsort" with the proper type (93)]
|
||||||
expected: FAIL
|
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]
|
[Window interface: calling showModalDialog(DOMString,any) on window with too few arguments must throw TypeError]
|
||||||
expected:
|
expected:
|
||||||
if not e10s: PASS
|
if not e10s: PASS
|
||||||
@ -2515,9 +2494,6 @@
|
|||||||
[Document interface: iframe.contentDocument must inherit property "onsort" with the proper type (149)]
|
[Document interface: iframe.contentDocument must inherit property "onsort" with the proper type (149)]
|
||||||
expected: FAIL
|
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)]
|
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "styleSheetSets" with the proper type (32)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@ -2665,9 +2641,6 @@
|
|||||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onsort" with the proper type (149)]
|
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onsort" with the proper type (149)]
|
||||||
expected: FAIL
|
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"]
|
[Location interface: window.location must have own property "ancestorOrigins"]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -1,21 +1,3 @@
|
|||||||
[toggleEvent.html]
|
[toggleEvent.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
prefs: [dom.details_element.enabled:true]
|
||||||
[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
|
|
||||||
|
|
||||||
|
@ -24,17 +24,42 @@
|
|||||||
<summary>Lorem ipsum</summary>
|
<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>
|
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
||||||
</details>
|
</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>
|
<script>
|
||||||
var t1 = async_test("Adding open to 'details' should fire a toggle event at the 'details' element"),
|
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"),
|
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"),
|
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"),
|
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"),
|
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'),
|
details1 = document.getElementById('details1'),
|
||||||
details2 = document.getElementById('details2'),
|
details2 = document.getElementById('details2'),
|
||||||
details3 = document.getElementById('details3'),
|
details3 = document.getElementById('details3'),
|
||||||
details4 = document.getElementById('details4'),
|
details4 = document.getElementById('details4'),
|
||||||
details6 = document.getElementById('details6'),
|
details6 = document.getElementById('details6'),
|
||||||
|
details7 = document.getElementById('details7'),
|
||||||
|
details8 = document.getElementById('details8'),
|
||||||
|
details9 = document.getElementById('details9'),
|
||||||
|
details10 = document.getElementById('details10'),
|
||||||
loop=false;
|
loop=false;
|
||||||
|
|
||||||
function testEvent(evt) {
|
function testEvent(evt) {
|
||||||
@ -90,4 +115,43 @@
|
|||||||
assert_true(loop);
|
assert_true(loop);
|
||||||
t6.done();
|
t6.done();
|
||||||
}), 0);
|
}), 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>
|
</script>
|
||||||
|
@ -415,6 +415,9 @@ NS_EVENT_MESSAGE(eEditorInput)
|
|||||||
NS_EVENT_MESSAGE(eSelectStart)
|
NS_EVENT_MESSAGE(eSelectStart)
|
||||||
NS_EVENT_MESSAGE(eSelectionChange)
|
NS_EVENT_MESSAGE(eSelectionChange)
|
||||||
|
|
||||||
|
// Details element events.
|
||||||
|
NS_EVENT_MESSAGE(eToggle)
|
||||||
|
|
||||||
#ifdef UNDEF_NS_EVENT_MESSAGE_FIRST_LAST
|
#ifdef UNDEF_NS_EVENT_MESSAGE_FIRST_LAST
|
||||||
#undef UNDEF_NS_EVENT_MESSAGE_FIRST_LAST
|
#undef UNDEF_NS_EVENT_MESSAGE_FIRST_LAST
|
||||||
#undef NS_EVENT_MESSAGE_FIRST_LAST
|
#undef NS_EVENT_MESSAGE_FIRST_LAST
|
||||||
|
Loading…
Reference in New Issue
Block a user