line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package HTML::DOM::EventTarget; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = '0.058'; |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
|
6
|
28
|
|
|
28
|
|
152
|
use strict; |
|
28
|
|
|
|
|
40
|
|
|
28
|
|
|
|
|
642
|
|
7
|
28
|
|
|
28
|
|
115
|
use warnings; |
|
28
|
|
|
|
|
55
|
|
|
28
|
|
|
|
|
647
|
|
8
|
28
|
|
|
28
|
|
115
|
no warnings qw ' utf8 parenthesis '; |
|
28
|
|
|
|
|
45
|
|
|
28
|
|
|
|
|
779
|
|
9
|
|
|
|
|
|
|
|
10
|
28
|
|
|
28
|
|
149
|
use Carp 'croak'; |
|
28
|
|
|
|
|
56
|
|
|
28
|
|
|
|
|
1212
|
|
11
|
28
|
|
|
28
|
|
141
|
use HTML::DOM::Event; |
|
28
|
|
|
|
|
41
|
|
|
28
|
|
|
|
|
929
|
|
12
|
28
|
|
|
28
|
|
153
|
use HTML::DOM::Exception qw 'UNSPECIFIED_EVENT_TYPE_ERR'; |
|
28
|
|
|
|
|
46
|
|
|
28
|
|
|
|
|
947
|
|
13
|
28
|
|
|
28
|
|
145
|
use Scalar::Util qw'refaddr blessed'; |
|
28
|
|
|
|
|
53
|
|
|
28
|
|
|
|
|
1183
|
|
14
|
28
|
|
|
28
|
|
10806
|
use HTML::DOM::_FieldHash; |
|
28
|
|
|
|
|
60
|
|
|
28
|
|
|
|
|
38062
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
fieldhashes \my( |
17
|
|
|
|
|
|
|
%evh, # event handlers |
18
|
|
|
|
|
|
|
%cevh, # capturing event handlers |
19
|
|
|
|
|
|
|
%aevh, # attribute event handlers |
20
|
|
|
|
|
|
|
); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 NAME |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
HTML::DOM::EventTarget - Perl implementation of the DOM EventTarget interface |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 VERSION |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
Version 0.058 |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head1 SYNOPSIS |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
use HTML::DOM; |
33
|
|
|
|
|
|
|
$doc = HTML::DOM->new; |
34
|
|
|
|
|
|
|
$doc->isa('HTML::DOM::EventTarget'); # true |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
$event = $doc->createEvent('MouseEvents'); |
37
|
|
|
|
|
|
|
$event->initEvent('click',1,1); |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
$doc->trigger_event('click'); |
40
|
|
|
|
|
|
|
$doc->dispatchEvent($event); |
41
|
|
|
|
|
|
|
# etc |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head1 DESCRIPTION |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
This class provides the W3C's EventTarget DOM interface. It serves as a |
46
|
|
|
|
|
|
|
base class for L and L, but any class you |
47
|
|
|
|
|
|
|
write can inherit from it. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
This class provides the methods listed under L, but will also use |
50
|
|
|
|
|
|
|
a few |
51
|
|
|
|
|
|
|
others |
52
|
|
|
|
|
|
|
defined by subclasses, if they are present: |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=over |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=item parentNode |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=item event_parent |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
These are used to determine the 'ancestry' of the event target, through |
61
|
|
|
|
|
|
|
which the event will be dispatched. For each object, starting with the |
62
|
|
|
|
|
|
|
target, the C method is called; if it doesn't exist or returns |
63
|
|
|
|
|
|
|
false, the C method is tried. If that fails, then the object |
64
|
|
|
|
|
|
|
is taken to be the topmost object. |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=item error_handler |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
The return value of this method, if it exists and returns one, is presumed |
69
|
|
|
|
|
|
|
to be a code ref, and is called whenever an event handler (listener) dies. |
70
|
|
|
|
|
|
|
If there is no C method that returns true, then |
71
|
|
|
|
|
|
|
C<< $target->ownerDocument->error_handler >> is used instead. If that |
72
|
|
|
|
|
|
|
fails, then errors are ignored. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=item event_listeners_enabled |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
If this method exists and returns false, then event handlers are not |
77
|
|
|
|
|
|
|
called. |
78
|
|
|
|
|
|
|
If there is no C method, |
79
|
|
|
|
|
|
|
then |
80
|
|
|
|
|
|
|
C<< $target->ownerDocument->event_listeners_enabled >> is used instead. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=item ownerDocument |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
See C and C. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=back |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head1 METHODS |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
If a subclass needs to store event handlers and listeners elsewhere (e.g., |
91
|
|
|
|
|
|
|
associating them with another object), it can override C, |
92
|
|
|
|
|
|
|
C, C and C. |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=over |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=item addEventListener($event_name, $listener, $capture) |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
The C<$listener> should be either a coderef or an object with a |
99
|
|
|
|
|
|
|
C method. (HTML::DOM does not implement any such object since |
100
|
|
|
|
|
|
|
it would just be a wrapper around a coderef anyway, but has support for |
101
|
|
|
|
|
|
|
them.) An object with C<&{}> overloading will also do. |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
C<$capture> is a boolean indicating whether this is to be triggered during |
104
|
|
|
|
|
|
|
the 'capture' phase. |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=cut |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub addEventListener { |
109
|
885
|
|
|
885
|
1
|
4735
|
my ($self,$name,$listener, $capture) = @_; |
110
|
|
|
|
|
|
|
(\(%cevh, %evh))[!$capture]->{$self} |
111
|
885
|
|
|
|
|
3795
|
{lc $name}{refaddr $listener} = $listener; |
112
|
885
|
|
|
|
|
1497
|
return; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=item removeEventListener($event_name, $listener, $capture) |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
The C<$listener> should be the same reference passed to |
119
|
|
|
|
|
|
|
C. |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=cut |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub removeEventListener { |
124
|
99
|
|
|
99
|
1
|
232
|
my ($self,$name,$listener, $capture) = @_; |
125
|
99
|
|
|
|
|
132
|
$name = lc $name; |
126
|
99
|
|
|
|
|
153
|
my $h = (\(%cevh, %evh))[!$capture]; |
127
|
|
|
|
|
|
|
exists $h->{$self} |
128
|
|
|
|
|
|
|
and exists $$h{$self}{$name} |
129
|
99
|
100
|
66
|
|
|
518
|
and delete $$h{$self}{$name}{refaddr $listener}; |
130
|
99
|
|
|
|
|
169
|
return; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=item on* (onthis, onthat, onclick, onfoo, etc.) |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
This applies to any all-lowercase method beginning with C. Basically, |
137
|
|
|
|
|
|
|
C<< $target->onclick(\&sub) >> is equivalent to |
138
|
|
|
|
|
|
|
C<< $target->addEventListener('click', \&sub, 0) >>, except that it |
139
|
|
|
|
|
|
|
replaces any event handler already assigned via C, returning it. |
140
|
|
|
|
|
|
|
C<< $target->onclick >> (without arguments) returns the event handler |
141
|
|
|
|
|
|
|
previously assigned to C if there is one. |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=cut |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub AUTOLOAD { |
146
|
3489
|
|
|
3489
|
|
16403
|
my($pack,$meth) = our $AUTOLOAD =~ /(.*)::(.*)/s; |
147
|
3489
|
100
|
|
|
|
24727
|
$meth =~ /^on([a-z]+)\z/ |
148
|
|
|
|
|
|
|
or die "Can't locate object method \"$meth\" via package " |
149
|
|
|
|
|
|
|
. qq'"$pack" at '.join' line ',(caller)[1,2] |
150
|
|
|
|
|
|
|
,. "\n"; |
151
|
13
|
|
|
|
|
41
|
shift->event_handler($1, @_); |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
0
|
|
|
sub DESTROY{} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=item event_handler ( $name ) |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=item event_handler ( $name, $new_value ) |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
This is an accessor method for event listeners created by HTML or DOM |
160
|
|
|
|
|
|
|
attributes beginning with 'on'. This is used internally by the C |
161
|
|
|
|
|
|
|
methods. You can use it directly for efficiency's sake. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
This method used to be called C, but that was a |
164
|
|
|
|
|
|
|
mistake, as there is a distinction between handlers and listeners. The old |
165
|
|
|
|
|
|
|
name is still available but will be removed in a future release. It simply |
166
|
|
|
|
|
|
|
calls C. |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=cut |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
sub event_handler { |
171
|
25
|
|
|
25
|
1
|
64
|
my ($self,$name) = (shift,shift); |
172
|
25
|
|
|
|
|
41
|
$name = lc $name; |
173
|
|
|
|
|
|
|
my $old = exists $aevh{$self} && exists $aevh{$self}{$name} |
174
|
25
|
|
66
|
|
|
137
|
&& $aevh{$self}{$name}; |
175
|
25
|
100
|
|
|
|
90
|
@_ and $aevh{$self}{$name} = shift; |
176
|
25
|
100
|
|
|
|
102
|
$old ||(); |
177
|
|
|
|
|
|
|
} |
178
|
2
|
|
|
2
|
0
|
6
|
sub attr_event_listener { shift->event_handler(@_) } |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=item get_event_listeners($event_name, $capture) |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
This is not a DOM method (hence the underscores in the name). It returns a |
184
|
|
|
|
|
|
|
list of all event listeners for the given event name. C<$capture> is a |
185
|
|
|
|
|
|
|
boolean that indicates which list to return, either 'capture' listeners or |
186
|
|
|
|
|
|
|
normal ones. |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
If there is an event handler for this event (and C<$capture> is false), |
189
|
|
|
|
|
|
|
then C tacks a wrapper for the event handler on to the |
190
|
|
|
|
|
|
|
end of the list it returns. |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=for comment |
193
|
|
|
|
|
|
|
This is no longer true. But we may need a similar warning in case other packages install listeners that must not be removed. |
194
|
|
|
|
|
|
|
B This method is intended mostly for internal use, but you can |
195
|
|
|
|
|
|
|
go ahead and use it if you like. Just beware that some of the event |
196
|
|
|
|
|
|
|
handlers returned may have been installed automatically by HTML::DOM, and |
197
|
|
|
|
|
|
|
are necessary for its internal workings, so don't go passing those to |
198
|
|
|
|
|
|
|
C and expect all to go well. |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=cut |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub get_event_listeners { # uses underscores because it is not a DOM method |
203
|
6535
|
|
|
6535
|
1
|
14010
|
my($self,$name,$capture) = @_; |
204
|
6535
|
|
|
|
|
8271
|
$name = lc $name; |
205
|
6535
|
|
|
|
|
12981
|
my $h = (\(%cevh, %evh))[!$capture]->{$self}; |
206
|
|
|
|
|
|
|
my @ret = $h && exists $$h{$name} |
207
|
6535
|
100
|
100
|
|
|
13953
|
? values %{$$h{$name}} |
|
1087
|
|
|
|
|
2651
|
|
208
|
|
|
|
|
|
|
: (); |
209
|
6535
|
100
|
100
|
|
|
16442
|
if(!$capture && exists $aevh{$self} && exists $aevh{$self}{$name} |
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
210
|
|
|
|
|
|
|
and defined (my $aevh = $aevh{$self}{$name})) { |
211
|
|
|
|
|
|
|
@ret, sub { |
212
|
10
|
100
|
66
|
10
|
|
67
|
my $ret = |
213
|
|
|
|
|
|
|
defined blessed $aevh && $aevh->can('call_with') |
214
|
|
|
|
|
|
|
? call_with $aevh $_[0]->currentTarget, $_[0] |
215
|
|
|
|
|
|
|
: &$aevh($_[0]); |
216
|
10
|
100
|
100
|
|
|
96
|
defined $ret |
|
|
100
|
|
|
|
|
|
217
|
|
|
|
|
|
|
&& ($name eq 'mouseover' ? $ret : !$ret) |
218
|
|
|
|
|
|
|
&& $_[0]->preventDefault; |
219
|
|
|
|
|
|
|
} |
220
|
13
|
|
|
|
|
62
|
} |
221
|
6522
|
|
|
|
|
9949
|
else { @ret } |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=item dispatchEvent($event_object) |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
$event_object is an object returned by HTML::DOM's C method, |
227
|
|
|
|
|
|
|
or any object that implements the interface documented in |
228
|
|
|
|
|
|
|
L. |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
C does not automatically call the handler passed to the |
231
|
|
|
|
|
|
|
document's C. It is expected that the code that |
232
|
|
|
|
|
|
|
calls this method will do that (see also L). |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
The return value is a boolean indicating whether the default action |
235
|
|
|
|
|
|
|
should be taken (i.e., whether preventDefault was I called). |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=for comment |
238
|
|
|
|
|
|
|
Actually, it's the event object itself (unless it was called in |
239
|
|
|
|
|
|
|
auto-vivacious mode and the event was never auto-vivved); but that’s an |
240
|
|
|
|
|
|
|
implementation detail that’s subject to change willy-nilly. |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
=cut |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
sub dispatchEvent { |
245
|
1339
|
|
|
1339
|
1
|
2423
|
_dispatch_event(shift, 1, shift); |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
sub _dispatch_event { # This is where all the work is. |
249
|
|
|
|
|
|
|
# We accept two different types of arg lists: |
250
|
|
|
|
|
|
|
# 1) $target->...($yes_it_is_an_event_object, $event_obj) |
251
|
|
|
|
|
|
|
# 2) $target->...($no_it's_not_an_event_object, |
252
|
|
|
|
|
|
|
# $event_category, \&arg_maker, %more_args) |
253
|
|
|
|
|
|
|
# The second is for autovivving the event object, as we do with |
254
|
|
|
|
|
|
|
# attr modifications, to avoid creating an attr node unnecessarily. |
255
|
|
|
|
|
|
|
# We init an event with (%more_args, &arg_maker). |
256
|
|
|
|
|
|
|
|
257
|
1924
|
|
|
1924
|
|
2969
|
my ($target, $event) = (shift,shift); |
258
|
1924
|
100
|
66
|
|
|
6605
|
$event &&= shift or my ($cat, $args, %args) = @_;; |
259
|
1924
|
100
|
|
|
|
4151
|
my $name = $event ? $event->type : $args{type}; |
260
|
|
|
|
|
|
|
|
261
|
1924
|
100
|
100
|
|
|
5788
|
die HTML::DOM::Exception->new(UNSPECIFIED_EVENT_TYPE_ERR, |
262
|
|
|
|
|
|
|
'The type of event has not been specified') |
263
|
|
|
|
|
|
|
unless defined $name and length $name; |
264
|
|
|
|
|
|
|
|
265
|
1918
|
100
|
100
|
|
|
6420
|
$event->_set_target($target) if $event && !$event->target; |
266
|
|
|
|
|
|
|
|
267
|
1918
|
|
|
|
|
3748
|
local *@; |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
# Check to see whether we are supposed to skip event handlers, and |
270
|
|
|
|
|
|
|
# short-circuit if that’s the case: |
271
|
|
|
|
|
|
|
Foo: { |
272
|
1918
|
|
|
|
|
2309
|
my $doc; |
|
1918
|
|
|
|
|
2031
|
|
273
|
|
|
|
|
|
|
my $sub = $target->can('event_listeners_enabled') |
274
|
1918
|
|
50
|
|
|
7647
|
|| (eval{$doc = $target->ownerDocument}||next Foo) |
275
|
|
|
|
|
|
|
->can('event_listeners_enabled') |
276
|
|
|
|
|
|
|
|| last Foo; |
277
|
1898
|
100
|
50
|
|
|
5045
|
&$sub($doc||$target) or return $event||1 |
|
|
|
66
|
|
|
|
|
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
# Basic event flow is as follows: |
281
|
|
|
|
|
|
|
# 1. The 'capturing' phase: Go through the node's ancestors, |
282
|
|
|
|
|
|
|
# starting from the top of the tree. For each one, trigger any |
283
|
|
|
|
|
|
|
# capture events it might have. |
284
|
|
|
|
|
|
|
# 2. Trigger events on the $target. |
285
|
|
|
|
|
|
|
# 3. 'Bubble-blowing' phase: Trigger events on the target's ances- |
286
|
|
|
|
|
|
|
# tors in reverse order (top last). |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
my $eh = eval{$target->error_handler} |
289
|
1914
|
|
100
|
|
|
2443
|
||eval{$target->ownerDocument->error_handler}; |
290
|
|
|
|
|
|
|
|
291
|
1914
|
|
|
|
|
4515
|
my @lineage = $target; |
292
|
|
|
|
|
|
|
{ |
293
|
1914
|
|
|
|
|
2249
|
push @lineage, eval{$lineage[-1]->parentNode} |
294
|
4895
|
|
100
|
|
|
5359
|
||eval{$lineage[-1]->event_parent} |
295
|
|
|
|
|
|
|
||last; |
296
|
|
|
|
|
|
|
redo |
297
|
2981
|
|
|
|
|
3728
|
} |
298
|
1914
|
|
|
|
|
3146
|
shift @lineage; # shouldn’t include the target |
299
|
|
|
|
|
|
|
# $lineage[-1] is the root, by the way |
300
|
|
|
|
|
|
|
|
301
|
1914
|
|
|
|
|
2255
|
my $initted; |
302
|
|
|
|
|
|
|
|
303
|
1914
|
|
|
|
|
3219
|
for (reverse @lineage) { # root first |
304
|
2981
|
|
|
|
|
4573
|
my @l = $_->get_event_listeners($name, 1); |
305
|
2981
|
100
|
66
|
|
|
4601
|
if(@l and !$initted++) { |
306
|
|
|
|
|
|
|
# ~~~ This occurs three times; it probably ought to |
307
|
|
|
|
|
|
|
# go it its own sub |
308
|
10
|
|
33
|
|
|
18
|
$event ||= do { |
309
|
0
|
|
0
|
|
|
0
|
(my $e = |
310
|
|
|
|
|
|
|
($target->ownerDocument||$target) |
311
|
|
|
|
|
|
|
->createEvent($cat) |
312
|
|
|
|
|
|
|
)->init( |
313
|
|
|
|
|
|
|
%args, &$args |
314
|
|
|
|
|
|
|
); |
315
|
0
|
0
|
|
|
|
0
|
$e->_set_target($target) unless $e->target; |
316
|
0
|
|
|
|
|
0
|
$e; |
317
|
|
|
|
|
|
|
}; |
318
|
10
|
|
|
|
|
41
|
$event->_set_eventPhase( |
319
|
|
|
|
|
|
|
HTML::DOM::Event::CAPTURING_PHASE); |
320
|
|
|
|
|
|
|
} |
321
|
2981
|
100
|
|
|
|
4573
|
$event-> _set_currentTarget($_) if @l; |
322
|
2981
|
|
|
|
|
4353
|
for(@l) { |
323
|
18
|
50
|
0
|
|
|
22
|
eval { |
324
|
18
|
50
|
33
|
|
|
73
|
defined blessed $_ && $_->can('handleEvent') ? |
325
|
|
|
|
|
|
|
$_->handleEvent($event) : &$_($event); |
326
|
18
|
|
|
|
|
1126
|
1 |
327
|
|
|
|
|
|
|
} or $eh and &$eh(); |
328
|
|
|
|
|
|
|
} |
329
|
2981
|
100
|
100
|
|
|
6048
|
return !cancelled $event if |
330
|
|
|
|
|
|
|
($event||next)->propagation_stopped; |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
|
333
|
1912
|
|
|
|
|
3619
|
my @l = $target->get_event_listeners($name); |
334
|
1912
|
100
|
|
|
|
3134
|
if(@l) { |
335
|
768
|
100
|
|
|
|
1674
|
unless ($initted++) { |
336
|
760
|
|
66
|
|
|
1349
|
$event ||= do { |
337
|
229
|
|
33
|
|
|
492
|
(my $e = |
338
|
|
|
|
|
|
|
($target->ownerDocument||$target) |
339
|
|
|
|
|
|
|
->createEvent($cat) |
340
|
|
|
|
|
|
|
)->init( |
341
|
|
|
|
|
|
|
%args, &$args |
342
|
|
|
|
|
|
|
); |
343
|
229
|
50
|
|
|
|
618
|
$e->_set_target($target) unless $e->target; |
344
|
229
|
|
|
|
|
531
|
$e; |
345
|
|
|
|
|
|
|
}; |
346
|
|
|
|
|
|
|
}; |
347
|
768
|
|
|
|
|
1977
|
$event->_set_eventPhase(HTML::DOM::Event::AT_TARGET); |
348
|
768
|
|
|
|
|
1376
|
$event->_set_currentTarget($target); |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
eval { |
351
|
780
|
50
|
33
|
|
|
2860
|
defined blessed $_ && $_->can('handleEvent') ? |
352
|
|
|
|
|
|
|
$_->handleEvent($event) : &$_($event); |
353
|
775
|
|
|
|
|
3285
|
1 |
354
|
1912
|
|
66
|
|
|
3012
|
} or $eh and &$eh() for @l; |
|
|
|
66
|
|
|
|
|
355
|
|
|
|
|
|
|
return +($event) x !cancelled $event if |
356
|
|
|
|
|
|
|
$event |
357
|
|
|
|
|
|
|
? $event->propagation_stopped || !$event->bubbles |
358
|
1912
|
100
|
100
|
|
|
4310
|
: !$args{propagates_up}; |
|
|
100
|
|
|
|
|
|
359
|
|
|
|
|
|
|
|
360
|
1512
|
|
|
|
|
1824
|
my $initted2; |
361
|
1512
|
|
|
|
|
2105
|
for (@lineage) { # root last |
362
|
1304
|
|
|
|
|
1881
|
my @l = $_->get_event_listeners($name); |
363
|
1304
|
100
|
|
|
|
1851
|
if(@l){ |
364
|
217
|
100
|
|
|
|
333
|
unless($initted++) { |
365
|
19
|
|
33
|
|
|
33
|
$event ||= do { |
366
|
0
|
|
0
|
|
|
0
|
(my $e = |
367
|
|
|
|
|
|
|
($target->ownerDocument||$target) |
368
|
|
|
|
|
|
|
->createEvent($cat) |
369
|
|
|
|
|
|
|
)->init( |
370
|
|
|
|
|
|
|
%args, &$args |
371
|
|
|
|
|
|
|
); |
372
|
0
|
0
|
|
|
|
0
|
$e->_set_target($target) |
373
|
|
|
|
|
|
|
unless $e->target; |
374
|
0
|
|
|
|
|
0
|
$e; |
375
|
|
|
|
|
|
|
}; |
376
|
|
|
|
|
|
|
} |
377
|
217
|
100
|
|
|
|
356
|
unless ($initted2++) { |
378
|
121
|
|
|
|
|
215
|
$event->_set_eventPhase( |
379
|
|
|
|
|
|
|
HTML::DOM::Event::BUBBLING_PHASE); |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
} |
382
|
1304
|
100
|
|
|
|
2159
|
$event-> _set_currentTarget($_) if @l; |
383
|
|
|
|
|
|
|
eval { |
384
|
223
|
50
|
33
|
|
|
750
|
defined blessed $_ && $_->can('handleEvent') ? |
385
|
|
|
|
|
|
|
$_->handleEvent($event) : &$_($event); |
386
|
223
|
|
|
|
|
1657
|
1 |
387
|
1304
|
|
0
|
|
|
1761
|
} or $eh and &$eh() for(@l); |
|
|
|
33
|
|
|
|
|
388
|
1304
|
100
|
100
|
|
|
2535
|
return +($event) x !cancelled $event |
389
|
|
|
|
|
|
|
if ($event||next)->propagation_stopped; |
390
|
|
|
|
|
|
|
} |
391
|
1510
|
|
100
|
|
|
4094
|
return +($event) x !($event||return 1)->cancelled ; |
392
|
|
|
|
|
|
|
} |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=item trigger_event($event, ...) |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
Here is another non-DOM method. C<$event> can be an event object or simply |
397
|
|
|
|
|
|
|
an event name. This method triggers an |
398
|
|
|
|
|
|
|
event for real, first calling C and then running the default |
399
|
|
|
|
|
|
|
action for the event unless an event listener cancels it. |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
It can take named args following the C<$event> arg. These are passed to the |
402
|
|
|
|
|
|
|
event object's C method. Any |
403
|
|
|
|
|
|
|
omitted args will be filled in with reasonable defaults. These are |
404
|
|
|
|
|
|
|
completely ignored if C<$event> is an event object. |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
Also, you can use the C arg to provide a coderef that will be |
407
|
|
|
|
|
|
|
called as the default event handler. L overrides it to do |
408
|
|
|
|
|
|
|
just that, so you shouldn't need to use this arg except on a custom |
409
|
|
|
|
|
|
|
subclass of EventTarget. |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
When C<$event> is an event name, C automatically chooses the |
412
|
|
|
|
|
|
|
right event class and a set of default args for that event name, so you can |
413
|
|
|
|
|
|
|
supply just a few. E.g., |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
$elem->trigger_event('click', shift => 1, button => 1); |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
=begin comment |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
Internal-only features: |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
The interface for this is very clunky, so I’m keeping it private for now. |
422
|
|
|
|
|
|
|
It only exists for the sake of the implementation, anyway. |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
The named args can contain DOMActivate_default => \&sub to specify a |
425
|
|
|
|
|
|
|
default handler for an event type. We don't use default => |
426
|
|
|
|
|
|
|
{ DOMActivate => \&sub } as I originally intended, because that would make |
427
|
|
|
|
|
|
|
it harder for multiple classes |
428
|
|
|
|
|
|
|
to say SUPER::trigger_event($evnt, ..._default => ) without clobbering each |
429
|
|
|
|
|
|
|
other. |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
And there's the 'create event object on demand' interface, which is as |
432
|
|
|
|
|
|
|
follows: |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
$thing->trigger_event('DOMAttrModified', auto_viv => \&arg_maker); |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
This does not automatically supply the view. |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=end comment |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
=cut |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
sub trigger_event { # non-DOM method |
443
|
1897
|
|
|
1897
|
1
|
10263
|
my ($target, $event, %args) = @_; |
444
|
1897
|
100
|
|
|
|
3680
|
if($args{auto_viv}) { |
445
|
|
|
|
|
|
|
# For efficiency’s sake, we skip creating the event object |
446
|
|
|
|
|
|
|
# here, and have _dispatch_event create the object on |
447
|
|
|
|
|
|
|
# demand, using the code ref that we pass to it. |
448
|
585
|
|
|
|
|
1212
|
my ($cat, @init_args) = HTML'DOM'Event'defaults($event); |
449
|
585
|
|
|
|
|
1339
|
unshift @init_args, type => $event; |
450
|
585
|
50
|
|
|
|
1258
|
if(my $rv = _dispatch_event( |
451
|
|
|
|
|
|
|
$target, 0, $cat, $args{auto_viv}, |
452
|
|
|
|
|
|
|
@init_args |
453
|
|
|
|
|
|
|
)) { |
454
|
|
|
|
|
|
|
my $def = |
455
|
|
|
|
|
|
|
$args{"$event\_default"} || |
456
|
585
|
|
100
|
|
|
4004
|
$args{"default"} |
457
|
|
|
|
|
|
|
|| return; |
458
|
3
|
50
|
|
|
|
9
|
unless (ref $rv) { |
459
|
|
|
|
|
|
|
($rv = |
460
|
|
|
|
|
|
|
HTML'DOM'Event'create_event($cat) |
461
|
|
|
|
|
|
|
)->init(my @args = |
462
|
3
|
|
|
|
|
9
|
@init_args, &{$args{auto_viv}} |
|
3
|
|
|
|
|
11
|
|
463
|
|
|
|
|
|
|
); |
464
|
3
|
|
|
|
|
16
|
$rv->_set_target($target); |
465
|
|
|
|
|
|
|
} |
466
|
3
|
|
|
|
|
8
|
&$def($rv); |
467
|
|
|
|
|
|
|
} |
468
|
3
|
|
|
|
|
84
|
return; |
469
|
|
|
|
|
|
|
} |
470
|
1312
|
|
|
|
|
1505
|
my $type; |
471
|
|
|
|
|
|
|
defined blessed $event && $event->isa('HTML::DOM::Event') |
472
|
|
|
|
|
|
|
? $type = $event->type |
473
|
1312
|
100
|
66
|
|
|
3491
|
: do { |
474
|
1308
|
|
|
|
|
1630
|
$type = $event; |
475
|
1308
|
|
|
|
|
2641
|
$event = HTML'DOM'Event'create_event(( |
476
|
|
|
|
|
|
|
my (undef, @init_args) = |
477
|
|
|
|
|
|
|
HTML'DOM'Event'defaults($type) |
478
|
|
|
|
|
|
|
)[0]); |
479
|
1308
|
|
|
|
|
4566
|
$event->init( |
480
|
|
|
|
|
|
|
type=>$type, |
481
|
|
|
|
|
|
|
@init_args, |
482
|
|
|
|
|
|
|
%args |
483
|
|
|
|
|
|
|
); |
484
|
|
|
|
|
|
|
}; |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
$target->dispatchEvent($event) and &{ |
487
|
1312
|
100
|
|
|
|
3561
|
$args{"$type\_default"} || |
488
|
|
|
|
|
|
|
$args{default} |
489
|
|
|
|
|
|
|
|| return |
490
|
1308
|
100
|
100
|
|
|
10529
|
}($event); |
491
|
128
|
|
|
|
|
22693
|
return; |
492
|
|
|
|
|
|
|
} |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
=back |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
=cut |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
1; |
500
|
|
|
|
|
|
|
__END__ |