Skip to content

Commit f53a847

Browse files
authored
Merge branch 'master' into task/1221-add-support-for-target-and-target-within
2 parents e944f29 + 4ef032f commit f53a847

File tree

5 files changed

+83
-6
lines changed

5 files changed

+83
-6
lines changed

.github/workflows/release.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ jobs:
107107

108108
- name: Configures Git
109109
run: |
110-
git config --local user.email "[email protected]"
111-
git config --local user.name "GitHub Action"
110+
git config --global user.name "${{ github.actor }}"
111+
git config --global user.email "$(git log --format='%ae' HEAD^!)"
112+
git remote set-url origin https://${{ secrets.GIT_REPOSITORY_URL_USERNAME }}:${{ secrets.GIT_REPOSITORY_URL_ACCESS_TOKEN }}@github.com/capricorn86/happy-dom.git
112113
113114
- name: Creates release branch
114115
run: |

packages/happy-dom/src/event/EventTarget.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ export default abstract class EventTarget implements IEventTarget {
208208
if ((<IEventListener>listener).handleEvent) {
209209
WindowErrorUtility.captureError(
210210
window,
211-
(<IEventListener>listener).handleEvent.bind(this, event)
211+
(<IEventListener>listener).handleEvent.bind(listener, event)
212212
);
213213
} else {
214214
WindowErrorUtility.captureError(

packages/happy-dom/src/mutation-observer/MutationObserver.ts

+39-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import DOMException from '../exception/DOMException.js';
21
import * as PropertySymbol from '../PropertySymbol.js';
32
import INode from '../nodes/node/INode.js';
43
import Node from '../nodes/node/Node.js';
@@ -34,13 +33,50 @@ export default class MutationObserver {
3433
*/
3534
public observe(target: INode, options: IMutationObserverInit): void {
3635
if (!target) {
37-
throw new DOMException(
36+
throw new TypeError(
3837
`Failed to execute 'observe' on 'MutationObserver': The first parameter "target" should be of type "Node".`
3938
);
4039
}
4140

41+
if (options && (options.attributeFilter || options.attributeOldValue)) {
42+
if (options.attributes === undefined) {
43+
options = Object.assign({}, options, {
44+
attributes: true,
45+
attributeFilter: options.attributeFilter,
46+
attributeOldValue: options.attributeOldValue
47+
});
48+
}
49+
50+
if (!options.attributes && options.attributeOldValue) {
51+
throw new TypeError(
52+
`Failed to execute 'observe' on 'MutationObserver': The options object may only set 'attributeOldValue' to true when 'attributes' is true or not present.`
53+
);
54+
}
55+
56+
if (!options.attributes && options.attributeFilter) {
57+
throw new TypeError(
58+
`Failed to execute 'observe' on 'MutationObserver': The options object may only set 'attributeFilter' when 'attributes' is true or not present.`
59+
);
60+
}
61+
}
62+
63+
if (options && options.characterDataOldValue) {
64+
if (options.characterData === undefined) {
65+
options = Object.assign({}, options, {
66+
characterData: true,
67+
characterDataOldValue: options.characterDataOldValue
68+
});
69+
}
70+
71+
if (!options.characterData && options.characterDataOldValue) {
72+
throw new TypeError(
73+
`Failed to execute 'observe' on 'MutationObserver': The options object may only set 'characterDataOldValue' to true when 'characterData' is true or not present.`
74+
);
75+
}
76+
}
77+
4278
if (!options || (!options.childList && !options.attributes && !options.characterData)) {
43-
throw new DOMException(
79+
throw new TypeError(
4480
`Failed to execute 'observe' on 'MutationObserver': The options object must set at least one of 'attributes', 'characterData', or 'childList' to true.`
4581
);
4682
}

packages/happy-dom/test/event/EventTarget.test.ts

+13
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,19 @@ describe('EventTarget', () => {
103103
eventTarget.dispatchEvent(dispatchedEvent);
104104
expect(scope).toBe(eventTarget);
105105
});
106+
107+
it('Event listener with handleEvent is called in the scope of the listener when calling dispatchEvent().', () => {
108+
let scope = null;
109+
const listener = {
110+
handleEvent(): void {
111+
scope = this;
112+
}
113+
};
114+
const dispatchedEvent = new Event(EVENT_TYPE);
115+
eventTarget.addEventListener(EVENT_TYPE, listener);
116+
eventTarget.dispatchEvent(dispatchedEvent);
117+
expect(scope).toBe(listener);
118+
});
106119
});
107120

108121
describe('removeEventListener()', () => {

packages/happy-dom/test/mutation-observer/MutationObserver.test.ts

+27
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,33 @@ describe('MutationObserver', () => {
4040
]);
4141
});
4242

43+
it('Throws TypeError for invalid options.', async () => {
44+
const div = document.createElement('div');
45+
const observer = new MutationObserver(() => {});
46+
expect(() => observer.observe(div, {})).toThrow(TypeError);
47+
});
48+
49+
it('Allows to omit "attributes" if "attributeOldValue" or "attributeFilter" is specified.', async () => {
50+
const div = document.createElement('div');
51+
const observer = new MutationObserver(() => {});
52+
expect(() => observer.observe(div, { attributes: false, attributeOldValue: true })).toThrow();
53+
expect(() =>
54+
observer.observe(div, { attributes: false, attributeFilter: ['style', 'class'] })
55+
).toThrow();
56+
57+
expect(() => observer.observe(div, { attributeOldValue: true })).not.toThrow();
58+
expect(() => observer.observe(div, { attributeFilter: ['style', 'class'] })).not.toThrow();
59+
});
60+
61+
it('Allows to omit "characterData" if "characterDataOldValue" is specified.', async () => {
62+
const text = document.createTextNode('old');
63+
const observer = new MutationObserver(() => {});
64+
expect(() =>
65+
observer.observe(text, { characterData: false, characterDataOldValue: true })
66+
).toThrow();
67+
expect(() => observer.observe(text, { characterDataOldValue: true })).not.toThrow();
68+
});
69+
4370
it('Observes attributes and old attribute values.', async () => {
4471
let records: MutationRecord[] = [];
4572
const div = document.createElement('div');

0 commit comments

Comments
 (0)