Skip to content

Commit cee03ab

Browse files
committed
fix: [#1176] Use localName correctly in Document.createElement() and Document.createElementNS()
1 parent b31a126 commit cee03ab

22 files changed

+563
-498
lines changed

packages/happy-dom/src/PropertySymbol.ts

+2
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,5 @@ export const content = Symbol('content');
149149
export const mode = Symbol('mode');
150150
export const host = Symbol('host');
151151
export const setURL = Symbol('setURL');
152+
export const localName = Symbol('localName');
153+
export const registedClass = Symbol('registedClass');

packages/happy-dom/src/config/ElementTag.ts

-130
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
export default <{ [key: string]: string }>{
2+
a: 'HTMLAnchorElement',
3+
abbr: 'HTMLElement',
4+
address: 'HTMLElement',
5+
area: 'HTMLElement',
6+
article: 'HTMLElement',
7+
aside: 'HTMLElement',
8+
audio: 'HTMLAudioElement',
9+
b: 'HTMLElement',
10+
base: 'HTMLBaseElement',
11+
bdi: 'HTMLElement',
12+
bdo: 'HTMLElement',
13+
blockquaote: 'HTMLElement',
14+
body: 'HTMLElement',
15+
template: 'HTMLTemplateElement',
16+
form: 'HTMLFormElement',
17+
input: 'HTMLInputElement',
18+
textarea: 'HTMLTextAreaElement',
19+
script: 'HTMLScriptElement',
20+
img: 'HTMLImageElement',
21+
link: 'HTMLLinkElement',
22+
style: 'HTMLStyleElement',
23+
label: 'HTMLLabelElement',
24+
slot: 'HTMLSlotElement',
25+
meta: 'HTMLMetaElement',
26+
blockquote: 'HTMLElement',
27+
br: 'HTMLElement',
28+
button: 'HTMLButtonElement',
29+
canvas: 'HTMLElement',
30+
caption: 'HTMLElement',
31+
cite: 'HTMLElement',
32+
code: 'HTMLElement',
33+
col: 'HTMLElement',
34+
colgroup: 'HTMLElement',
35+
data: 'HTMLElement',
36+
datalist: 'HTMLElement',
37+
dd: 'HTMLElement',
38+
del: 'HTMLElement',
39+
details: 'HTMLElement',
40+
dfn: 'HTMLElement',
41+
dialog: 'HTMLDialogElement',
42+
div: 'HTMLElement',
43+
dl: 'HTMLElement',
44+
dt: 'HTMLElement',
45+
em: 'HTMLElement',
46+
embed: 'HTMLElement',
47+
fieldset: 'HTMLElement',
48+
figcaption: 'HTMLElement',
49+
figure: 'HTMLElement',
50+
footer: 'HTMLElement',
51+
h1: 'HTMLElement',
52+
h2: 'HTMLElement',
53+
h3: 'HTMLElement',
54+
h4: 'HTMLElement',
55+
h5: 'HTMLElement',
56+
h6: 'HTMLElement',
57+
head: 'HTMLElement',
58+
header: 'HTMLElement',
59+
hgroup: 'HTMLElement',
60+
hr: 'HTMLElement',
61+
html: 'HTMLElement',
62+
i: 'HTMLElement',
63+
iframe: 'HTMLIFrameElement',
64+
ins: 'HTMLElement',
65+
kbd: 'HTMLElement',
66+
legend: 'HTMLElement',
67+
li: 'HTMLElement',
68+
main: 'HTMLElement',
69+
map: 'HTMLElement',
70+
mark: 'HTMLElement',
71+
math: 'HTMLElement',
72+
menu: 'HTMLElement',
73+
menuitem: 'HTMLElement',
74+
meter: 'HTMLElement',
75+
nav: 'HTMLElement',
76+
noscript: 'HTMLElement',
77+
object: 'HTMLElement',
78+
ol: 'HTMLElement',
79+
optgroup: 'HTMLOptGroupElement',
80+
option: 'HTMLOptionElement',
81+
output: 'HTMLElement',
82+
p: 'HTMLElement',
83+
param: 'HTMLElement',
84+
picture: 'HTMLElement',
85+
pre: 'HTMLElement',
86+
progress: 'HTMLElement',
87+
q: 'HTMLElement',
88+
rb: 'HTMLElement',
89+
rp: 'HTMLElement',
90+
rt: 'HTMLElement',
91+
rtc: 'HTMLElement',
92+
ruby: 'HTMLElement',
93+
s: 'HTMLElement',
94+
samp: 'HTMLElement',
95+
section: 'HTMLElement',
96+
select: 'HTMLSelectElement',
97+
small: 'HTMLElement',
98+
source: 'HTMLElement',
99+
span: 'HTMLElement',
100+
strong: 'HTMLElement',
101+
sub: 'HTMLElement',
102+
summary: 'HTMLElement',
103+
sup: 'HTMLElement',
104+
table: 'HTMLElement',
105+
tbody: 'HTMLElement',
106+
td: 'HTMLElement',
107+
tfoot: 'HTMLElement',
108+
th: 'HTMLElement',
109+
thead: 'HTMLElement',
110+
time: 'HTMLElement',
111+
title: 'HTMLElement',
112+
tr: 'HTMLElement',
113+
track: 'HTMLElement',
114+
u: 'HTMLElement',
115+
ul: 'HTMLElement',
116+
var: 'HTMLElement',
117+
video: 'HTMLVideoElement',
118+
wbr: 'HTMLElement'
119+
};
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export default {
22
html: 'http://www.w3.org/1999/xhtml',
33
svg: 'http://www.w3.org/2000/svg',
4-
mathML: 'http://www.w3.org/1998/Math/MathML'
4+
mathML: 'http://www.w3.org/1998/Math/MathML',
5+
xmlns: 'http://www.w3.org/2000/xmlns/'
56
};

packages/happy-dom/src/custom-element/CustomElementRegistry.ts

+16-10
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default class CustomElementRegistry {
1010
public [PropertySymbol.registry]: {
1111
[k: string]: { elementClass: typeof HTMLElement; extends: string };
1212
} = {};
13+
public [PropertySymbol.registedClass]: Map<typeof HTMLElement, string> = new Map();
1314
public [PropertySymbol.callbacks]: { [k: string]: (() => void)[] } = {};
1415

1516
/**
@@ -27,16 +28,27 @@ export default class CustomElementRegistry {
2728
): void {
2829
if (!this.#isValidCustomElementName(name)) {
2930
throw new DOMException(
30-
"Failed to execute 'define' on 'CustomElementRegistry': \"" +
31-
name +
32-
'" is not a valid custom element name.'
31+
`Failed to execute 'define' on 'CustomElementRegistry': "${name}" is not a valid custom element name`
32+
);
33+
}
34+
35+
if (this[PropertySymbol.registry][name]) {
36+
throw new DOMException(
37+
`Failed to execute 'define' on 'CustomElementRegistry': the name "${name}" has already been used with this registry`
38+
);
39+
}
40+
41+
if (this[PropertySymbol.registedClass].has(elementClass)) {
42+
throw new DOMException(
43+
"Failed to execute 'define' on 'CustomElementRegistry': this constructor has already been used with this registry"
3344
);
3445
}
3546

3647
this[PropertySymbol.registry][name] = {
3748
elementClass,
3849
extends: options && options.extends ? options.extends.toLowerCase() : null
3950
};
51+
this[PropertySymbol.registedClass].set(elementClass, name);
4052

4153
// ObservedAttributes should only be called once by CustomElementRegistry (see #117)
4254
if (elementClass.prototype.attributeChangedCallback) {
@@ -98,13 +110,7 @@ export default class CustomElementRegistry {
98110
* @returns Found tag name or `null`.
99111
*/
100112
public getName(elementClass: typeof HTMLElement): string | null {
101-
// For loops are faster than find()
102-
for (const name of Object.keys(this[PropertySymbol.registry])) {
103-
if (this[PropertySymbol.registry][name].elementClass === elementClass) {
104-
return name;
105-
}
106-
}
107-
return null;
113+
return this[PropertySymbol.registedClass].get(elementClass) || null;
108114
}
109115

110116
/**

0 commit comments

Comments
 (0)