1616// You should have received a copy of the GNU Affero General Public License
1717// along with this program. If not, see <https://www.gnu.org/licenses/>.
1818
19+ const std = @import ("std" );
20+ const log = std .log .scoped (.mouse_event );
21+
1922const parser = @import ("../netsurf.zig" );
2023const Event = @import ("event.zig" ).Event ;
2124const JsObject = @import ("../env.zig" ).JsObject ;
2225
26+ // TODO: We currently don't have a UIEvent interface so we skip it in the prototype chain.
27+ // https://developer.mozilla.org/en-US/docs/Web/API/UIEvent
28+ const UIEvent = Event ;
29+
2330// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
2431pub const MouseEvent = struct {
2532 pub const Self = parser .MouseEvent ;
26- pub const prototype = * Event ;
33+ pub const prototype = * UIEvent ;
34+
35+ const MouseButton = enum (u16 ) {
36+ main_button = 0 ,
37+ auxillary_button = 1 ,
38+ secondary_button = 2 ,
39+ fourth_button = 3 ,
40+ fifth_button = 4 ,
41+ };
2742
2843 const MouseEventInit = struct {
2944 screenX : i32 = 0 ,
@@ -34,13 +49,14 @@ pub const MouseEvent = struct {
3449 shiftKey : bool = false ,
3550 altKey : bool = false ,
3651 metaKey : bool = false ,
37- button : u16 = 0 ,
52+ button : MouseButton = .main_button ,
3853 };
3954
40- pub fn constructor (event_type : []const u8 , opts_ : ? MouseEventInit ) ! * Self {
55+ pub fn constructor (event_type : []const u8 , opts_ : ? MouseEventInit ) ! * parser.MouseEvent {
4156 const opts = opts_ orelse MouseEventInit {};
4257
43- const mouse_event = try parser .mouseEventCreate ();
58+ var mouse_event = try parser .mouseEventCreate ();
59+ try parser .eventSetInternalType (@ptrCast (& mouse_event ), .mouse_event );
4460
4561 try parser .mouseEventInit (mouse_event , event_type , .{
4662 .x = opts .clientX ,
@@ -49,35 +65,43 @@ pub const MouseEvent = struct {
4965 .shift = opts .shiftKey ,
5066 .alt = opts .altKey ,
5167 .meta = opts .metaKey ,
52- .button = opts .button ,
68+ .button = @intFromEnum ( opts .button ) ,
5369 });
5470
71+ if (! std .mem .eql (u8 , event_type , "click" )) {
72+ log .warn ("MouseEvent currently only supports listeners for 'click' events!" , .{});
73+ }
74+
5575 return mouse_event ;
5676 }
5777
78+ pub fn get_button (self : * parser.MouseEvent ) u16 {
79+ return self .button ;
80+ }
81+
5882 // These is just an alias for clientX.
59- pub fn get_x (self : * Self ) ! i32 {
83+ pub fn get_x (self : * parser.MouseEvent ) i32 {
6084 return self .cx ;
6185 }
6286
6387 // These is just an alias for clientY.
64- pub fn get_y (self : * Self ) ! i32 {
88+ pub fn get_y (self : * parser.MouseEvent ) i32 {
6589 return self .cy ;
6690 }
6791
68- pub fn get_clientX (self : * Self ) ! i32 {
92+ pub fn get_clientX (self : * parser.MouseEvent ) i32 {
6993 return self .cx ;
7094 }
7195
72- pub fn get_clientY (self : * Self ) ! i32 {
96+ pub fn get_clientY (self : * parser.MouseEvent ) i32 {
7397 return self .cy ;
7498 }
7599
76- pub fn get_screenX (self : * Self ) ! i32 {
100+ pub fn get_screenX (self : * parser.MouseEvent ) i32 {
77101 return self .sx ;
78102 }
79103
80- pub fn get_screenY (self : * Self ) ! i32 {
104+ pub fn get_screenY (self : * parser.MouseEvent ) i32 {
81105 return self .sy ;
82106 }
83107};
@@ -88,6 +112,7 @@ test "Browser.MouseEvent" {
88112 defer runner .deinit ();
89113
90114 try runner .testCases (&.{
115+ // Default MouseEvent
91116 .{ "let event = new MouseEvent('click')" , "undefined" },
92117 .{ "event.type" , "click" },
93118 .{ "event instanceof MouseEvent" , "true" },
@@ -96,10 +121,20 @@ test "Browser.MouseEvent" {
96121 .{ "event.clientY" , "0" },
97122 .{ "event.screenX" , "0" },
98123 .{ "event.screenY" , "0" },
99- .{ "let new_event = new MouseEvent('click2', { 'clientX': 10, 'clientY': 20 })" , "undefined" },
124+ // MouseEvent with parameters
125+ .{ "let new_event = new MouseEvent('click', { 'button': 0, 'clientX': 10, 'clientY': 20 })" , "undefined" },
126+ .{ "new_event.button" , "0" },
100127 .{ "new_event.x" , "10" },
101128 .{ "new_event.y" , "20" },
102129 .{ "new_event.screenX" , "10" },
103130 .{ "new_event.screenY" , "20" },
131+ // MouseEvent Listener
132+ .{ "let me = new MouseEvent('click')" , "undefined" },
133+ .{ "me instanceof Event" , "true" },
134+ .{ "var eevt = null; function ccbk(event) { eevt = event; }" , "undefined" },
135+ .{ "document.addEventListener('click', ccbk)" , "undefined" },
136+ .{ "document.dispatchEvent(me)" , "true" },
137+ .{ "eevt.type" , "click" },
138+ .{ "eevt instanceof MouseEvent" , "true" },
104139 }, .{});
105140}
0 commit comments