1'use strict';
2
3require('../common');
4const { test, assert_equals, assert_unreached } =
5  require('../common/wpt').harness;
6
7// Manually ported from: https://github.com/web-platform-tests/wpt/blob/6cef1d2087d6a07d7cc6cee8cf207eec92e27c5f/dom/events/EventTarget-this-of-listener.html
8
9// Mock document
10const document = {
11  createElement: () => new EventTarget(),
12  createTextNode: () => new EventTarget(),
13  createDocumentFragment: () => new EventTarget(),
14  createComment: () => new EventTarget(),
15  createProcessingInstruction: () => new EventTarget(),
16};
17
18test(() => {
19  const nodes = [
20    document.createElement('p'),
21    document.createTextNode('some text'),
22    document.createDocumentFragment(),
23    document.createComment('a comment'),
24    document.createProcessingInstruction('target', 'data'),
25  ];
26
27  let callCount = 0;
28  for (const node of nodes) {
29    node.addEventListener('someevent', function() {
30      ++callCount;
31      assert_equals(this, node);
32    });
33
34    node.dispatchEvent(new Event('someevent'));
35  }
36
37  assert_equals(callCount, nodes.length);
38}, 'the this value inside the event listener callback should be the node');
39
40test(() => {
41  const nodes = [
42    document.createElement('p'),
43    document.createTextNode('some text'),
44    document.createDocumentFragment(),
45    document.createComment('a comment'),
46    document.createProcessingInstruction('target', 'data'),
47  ];
48
49  let callCount = 0;
50  for (const node of nodes) {
51    const handler = {};
52
53    node.addEventListener('someevent', handler);
54    handler.handleEvent = function() {
55      ++callCount;
56      assert_equals(this, handler);
57    };
58
59    node.dispatchEvent(new Event('someevent'));
60  }
61
62  assert_equals(callCount, nodes.length);
63}, 'addEventListener should not require handleEvent to be defined on object listeners');
64
65test(() => {
66  const nodes = [
67    document.createElement('p'),
68    document.createTextNode('some text'),
69    document.createDocumentFragment(),
70    document.createComment('a comment'),
71    document.createProcessingInstruction('target', 'data'),
72  ];
73
74  let callCount = 0;
75  for (const node of nodes) {
76    function handler() {
77      ++callCount;
78      assert_equals(this, node);
79    }
80
81    handler.handleEvent = () => {
82      assert_unreached('should not call the handleEvent method on a function');
83    };
84
85    node.addEventListener('someevent', handler);
86
87    node.dispatchEvent(new Event('someevent'));
88  }
89
90  assert_equals(callCount, nodes.length);
91}, 'handleEvent properties added to a function before addEventListener are not reached');
92
93test(() => {
94  const nodes = [
95    document.createElement('p'),
96    document.createTextNode('some text'),
97    document.createDocumentFragment(),
98    document.createComment('a comment'),
99    document.createProcessingInstruction('target', 'data'),
100  ];
101
102  let callCount = 0;
103  for (const node of nodes) {
104    function handler() {
105      ++callCount;
106      assert_equals(this, node);
107    }
108
109    node.addEventListener('someevent', handler);
110
111    handler.handleEvent = () => {
112      assert_unreached('should not call the handleEvent method on a function');
113    };
114
115    node.dispatchEvent(new Event('someevent'));
116  }
117
118  assert_equals(callCount, nodes.length);
119}, 'handleEvent properties added to a function after addEventListener are not reached');
120