Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6e7899b

Browse filesBrowse files
committed
feat: implement Event and EventTarget
1 parent f3accae commit 6e7899b
Copy full SHA for 6e7899b

File tree

Expand file treeCollapse file tree

5 files changed

+59
-36
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+59
-36
lines changed

‎packages/core/data/dom-events/dom-event.ts

Copy file name to clipboardExpand all lines: packages/core/data/dom-events/dom-event.ts
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const timeOrigin = Date.now();
1010
*/
1111
const emptyArray = [] as const;
1212

13-
export class DOMEvent {
13+
export class DOMEvent implements Event {
1414
/**
1515
* @private
1616
* Internal API to facilitate testing - to be removed once we've completed
@@ -119,7 +119,7 @@ export class DOMEvent {
119119

120120
// From CustomEvent rather than Event. Can consider factoring out this
121121
// aspect into DOMCustomEvent.
122-
private readonly detail: unknown | null;
122+
readonly detail: unknown | null;
123123

124124
private propagationState: EventPropagationState = EventPropagationState.resume;
125125

‎packages/core/data/observable/index.ts

Copy file name to clipboardExpand all lines: packages/core/data/observable/index.ts
+39-24Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import type { ViewBase } from '../../ui/core/view-base';
22
import { DOMEvent } from '../dom-events/dom-event';
33

4-
import { Observable as ObservableDefinition, WrappedValue as WrappedValueDefinition } from '.';
5-
64
/**
75
* Base event data.
86
*/
@@ -51,7 +49,7 @@ let _wrappedIndex = 0;
5149
* By default property change will not be fired for a same object.
5250
* By wrapping object into a WrappedValue instance `same object restriction` will be passed.
5351
*/
54-
export class WrappedValue implements WrappedValueDefinition {
52+
export class WrappedValue {
5553
/**
5654
* Creates an instance of WrappedValue object.
5755
* @param wrapped - the real value which should be wrapped.
@@ -96,7 +94,7 @@ const _globalEventHandlers: {
9694
* Please note that should you be using the `new Observable({})` constructor, it is **obsolete** since v3.0,
9795
* and you have to migrate to the "data/observable" `fromObject({})` or the `fromObjectRecursive({})` functions.
9896
*/
99-
export class Observable implements ObservableDefinition {
97+
export class Observable implements EventTarget {
10098
/**
10199
* String value used when hooking to propertyChange event.
102100
*/
@@ -187,27 +185,27 @@ export class Observable implements ObservableDefinition {
187185
* @param thisArg An optional parameter which when set will be used as "this" in callback method call.
188186
* @param options An optional parameter. If passed as a boolean, configures the useCapture value. Otherwise, specifies options.
189187
*/
190-
public addEventListener(eventNames: string, callback: (data: EventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void {
188+
public addEventListener(eventNames: string, callback: EventListenerOrEventListenerObject | ((data: EventData) => void), thisArg?: any, options?: AddEventListenerOptions | boolean): void {
191189
if (typeof eventNames !== 'string') {
192190
throw new TypeError('Events name(s) must be string.');
193191
}
194192

195193
if (typeof callback !== 'function') {
196-
throw new TypeError('callback must be function.');
194+
throw new TypeError('Callback must be function.');
197195
}
198196

199197
const events = eventNames.trim().split(eventDelimiterPattern);
200198
for (let i = 0, l = events.length; i < l; i++) {
201199
const event = events[i];
202200
const list = this.getEventList(event, true);
203-
if (Observable._indexOfListener(list, callback, thisArg, options) >= 0) {
201+
if (Observable._indexOfListener(list, callback as (data: EventData) => void, thisArg, options) >= 0) {
204202
// Don't allow addition of duplicate event listeners.
205203
continue;
206204
}
207205

208206
// TODO: Performance optimization - if we do not have the thisArg specified, do not wrap the callback in additional object (ObserveEntry)
209207
list.push({
210-
callback,
208+
callback: callback as (data: EventData) => void,
211209
thisArg,
212210
capture: getCaptureFromOptions(options),
213211
passive: getPassiveFromOptions(options),
@@ -222,7 +220,7 @@ export class Observable implements ObservableDefinition {
222220
* @param thisArg An optional parameter which when set will be used to refine search of the correct callback which will be removed as event listener.
223221
* @param options An optional parameter. If passed as a boolean, configures the useCapture value. Otherwise, specifies options.
224222
*/
225-
public removeEventListener(eventNames: string, callback?: (data: EventData) => void, thisArg?: any, options?: EventListenerOptions | boolean): void {
223+
public removeEventListener(eventNames: string, callback?: EventListenerOrEventListenerObject | ((data: EventData) => void), thisArg?: any, options?: EventListenerOptions | boolean): void {
226224
if (typeof eventNames !== 'string') {
227225
throw new TypeError('Events name(s) must be string.');
228226
}
@@ -238,14 +236,16 @@ export class Observable implements ObservableDefinition {
238236
}
239237

240238
const list = this.getEventList(event, false);
241-
if (list) {
242-
const index = Observable._indexOfListener(list, callback, thisArg, options);
243-
if (index >= 0) {
244-
list.splice(index, 1);
245-
}
246-
if (list.length === 0) {
247-
delete this._observers[event];
248-
}
239+
if (!list) {
240+
continue;
241+
}
242+
243+
const index = Observable._indexOfListener(list, callback as (data: EventData) => void, thisArg, options);
244+
if (index >= 0) {
245+
list.splice(index, 1);
246+
}
247+
if (list.length === 0) {
248+
delete this._observers[event];
249249
}
250250
}
251251
}
@@ -263,13 +263,13 @@ export class Observable implements ObservableDefinition {
263263
this.removeEventListener(eventName, callback, thisArg, options);
264264
}
265265

266-
public static removeEventListener(eventName: string, callback?: (data: EventData) => void, thisArg?: any, options?: EventListenerOptions | boolean): void {
266+
public static removeEventListener(eventName: string, callback?: EventListenerOrEventListenerObject | ((data: EventData) => void), thisArg?: any, options?: EventListenerOptions | boolean): void {
267267
if (typeof eventName !== 'string') {
268268
throw new TypeError('Event must be string.');
269269
}
270270

271271
if (callback && typeof callback !== 'function') {
272-
throw new TypeError('callback must be function.');
272+
throw new TypeError('Callback, if provided, must be function.');
273273
}
274274

275275
const eventClass = this.name === 'Observable' ? '*' : this.name;
@@ -281,7 +281,7 @@ export class Observable implements ObservableDefinition {
281281

282282
const events = _globalEventHandlers[eventClass][eventName];
283283
if (callback) {
284-
const index = Observable._indexOfListener(events, callback, thisArg, options);
284+
const index = Observable._indexOfListener(events, callback as (data: EventData) => void, thisArg, options);
285285
if (index >= 0) {
286286
events.splice(index, 1);
287287
}
@@ -302,13 +302,13 @@ export class Observable implements ObservableDefinition {
302302
}
303303
}
304304

305-
public static addEventListener(eventName: string, callback: (data: EventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void {
305+
public static addEventListener(eventName: string, callback: EventListenerOrEventListenerObject | ((data: EventData) => void), thisArg?: any, options?: AddEventListenerOptions | boolean): void {
306306
if (typeof eventName !== 'string') {
307307
throw new TypeError('Event must be string.');
308308
}
309309

310310
if (typeof callback !== 'function') {
311-
throw new TypeError('callback must be function.');
311+
throw new TypeError('Callback must be function.');
312312
}
313313

314314
const eventClass = this.name === 'Observable' ? '*' : this.name;
@@ -320,13 +320,13 @@ export class Observable implements ObservableDefinition {
320320
}
321321

322322
const list = _globalEventHandlers[eventClass][eventName];
323-
if (Observable._indexOfListener(list, callback, thisArg, options) >= 0) {
323+
if (Observable._indexOfListener(list, callback as (data: EventData) => void, thisArg, options) >= 0) {
324324
// Don't allow addition of duplicate event listeners.
325325
return;
326326
}
327327

328328
_globalEventHandlers[eventClass][eventName].push({
329-
callback,
329+
callback: callback as (data: EventData) => void,
330330
thisArg,
331331
capture: getCaptureFromOptions(options),
332332
passive: getPassiveFromOptions(options),
@@ -388,6 +388,21 @@ export class Observable implements ObservableDefinition {
388388
});
389389
}
390390

391+
dispatchEvent(event: DOMEvent): boolean {
392+
const data = {
393+
eventName: event.type,
394+
object: this,
395+
detail: event.detail,
396+
};
397+
398+
return event.dispatchTo({
399+
target: this,
400+
data,
401+
getGlobalEventHandlersPreHandling: () => this._getGlobalEventHandlers(data, 'First'),
402+
getGlobalEventHandlersPostHandling: () => this._getGlobalEventHandlers(data, ''),
403+
});
404+
}
405+
391406
private _getGlobalEventHandlers(data: EventData, eventType: 'First' | ''): ListenerEntry[] {
392407
const eventClass = data.object?.constructor?.name;
393408
const globalEventHandlersForOwnClass = _globalEventHandlers[eventClass]?.[`${data.eventName}${eventType}`] ?? [];

‎packages/core/ui/core/view/view-common.ts

Copy file name to clipboardExpand all lines: packages/core/ui/core/view/view-common.ts
+14-6Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,11 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
293293
return this._gestureObservers[type] || [];
294294
}
295295

296-
public addEventListener(arg: string | GestureTypes, callback: (data: EventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void {
296+
public addEventListener(arg: string | GestureTypes, callback: EventListenerOrEventListenerObject | ((data: EventData) => void), thisArg?: any, options?: AddEventListenerOptions | boolean): void {
297+
if (typeof callback !== 'function') {
298+
throw new TypeError('Callback must be function.');
299+
}
300+
297301
// To avoid a full refactor of the Gestures system when migrating to DOM
298302
// Events, we mirror the this._gestureObservers record, creating
299303
// corresponding DOM Event listeners for each gesture.
@@ -309,7 +313,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
309313
// the same time).
310314

311315
if (typeof arg === 'number') {
312-
this._observe(arg, callback, thisArg, options);
316+
this._observe(arg, callback as (data: EventData) => void, thisArg, options);
313317
super.addEventListener(gestureToString(arg), callback, thisArg, options);
314318
return;
315319
}
@@ -321,15 +325,19 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
321325
for (const event of events) {
322326
const gesture = gestureFromString(event);
323327
if (gesture && !this._isEvent(arg)) {
324-
this._observe(gesture, callback, thisArg, options);
328+
this._observe(gesture, callback as (data: EventData) => void, thisArg, options);
325329
}
326330
super.addEventListener(event, callback, thisArg, options);
327331
}
328332
}
329333

330-
public removeEventListener(arg: string | GestureTypes, callback?: (data: EventData) => void, thisArg?: any, options?: EventListenerOptions | boolean): void {
334+
public removeEventListener(arg: string | GestureTypes, callback?: EventListenerOrEventListenerObject | ((data: EventData) => void), thisArg?: any, options?: EventListenerOptions | boolean): void {
335+
if (callback && typeof callback !== 'function') {
336+
throw new TypeError('Callback, if provided, must be function.');
337+
}
338+
331339
if (typeof arg === 'number') {
332-
this._disconnectGestureObservers(arg, callback, thisArg, options);
340+
this._disconnectGestureObservers(arg, callback as (data: EventData) => void, thisArg, options);
333341
super.removeEventListener(gestureToString(arg), callback, thisArg, options);
334342
return;
335343
}
@@ -339,7 +347,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
339347
for (const event of events) {
340348
const gesture = gestureFromString(event);
341349
if (gesture && !this._isEvent(arg)) {
342-
this._disconnectGestureObservers(gesture, callback, thisArg, options);
350+
this._disconnectGestureObservers(gesture, callback as (data: EventData) => void, thisArg, options);
343351
}
344352
super.removeEventListener(event, callback, thisArg, options);
345353
}

‎packages/core/ui/scroll-view/scroll-view-common.ts

Copy file name to clipboardExpand all lines: packages/core/ui/scroll-view/scroll-view-common.ts
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export abstract class ScrollViewBase extends ContentView implements ScrollViewDe
1616
public scrollBarIndicatorVisible: boolean;
1717
public isScrollEnabled: boolean;
1818

19-
public addEventListener(arg: string, callback: (data: EventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void {
19+
public addEventListener(arg: string, callback: EventListenerOrEventListenerObject | ((data: EventData) => void), thisArg?: any, options?: AddEventListenerOptions | boolean): void {
2020
super.addEventListener(arg, callback, thisArg, options);
2121

2222
if (arg === ScrollViewBase.scrollEvent) {
@@ -25,7 +25,7 @@ export abstract class ScrollViewBase extends ContentView implements ScrollViewDe
2525
}
2626
}
2727

28-
public removeEventListener(arg: string, callback?: (data: EventData) => void, thisArg?: any, options?: EventListenerOptions | boolean): void {
28+
public removeEventListener(arg: string, callback?: EventListenerOrEventListenerObject | ((data: EventData) => void), thisArg?: any, options?: EventListenerOptions | boolean): void {
2929
super.removeEventListener(arg, callback, thisArg, options);
3030

3131
if (arg === ScrollViewBase.scrollEvent) {

‎packages/core/ui/text-base/span.ts

Copy file name to clipboardExpand all lines: packages/core/ui/text-base/span.ts
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,12 @@ export class Span extends ViewBase implements SpanDefinition {
8181
return this._tappable;
8282
}
8383

84-
addEventListener(arg: string, callback: (data: EventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void {
84+
addEventListener(arg: string, callback: EventListenerOrEventListenerObject | ((data: EventData) => void), thisArg?: any, options?: AddEventListenerOptions | boolean): void {
8585
super.addEventListener(arg, callback, thisArg, options);
8686
this._setTappable(this.hasListeners(Span.linkTapEvent));
8787
}
8888

89-
removeEventListener(arg: string, callback?: (data: EventData) => void, thisArg?: any, options?: EventListenerOptions | boolean): void {
89+
removeEventListener(arg: string, callback?: EventListenerOrEventListenerObject | ((data: EventData) => void), thisArg?: any, options?: EventListenerOptions | boolean): void {
9090
super.removeEventListener(arg, callback, thisArg, options);
9191
this._setTappable(this.hasListeners(Span.linkTapEvent));
9292
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.