happy-dom 7.6.6 → 7.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of happy-dom might be problematic. Click here for more details.
- package/lib/config/ElementTag.d.ts +2 -1
- package/lib/config/ElementTag.js +2 -1
- package/lib/config/ElementTag.js.map +1 -1
- package/lib/dom-token-list/DOMTokenList.js +1 -1
- package/lib/dom-token-list/DOMTokenList.js.map +1 -1
- package/lib/nodes/element/Element.d.ts +0 -4
- package/lib/nodes/element/Element.js +6 -10
- package/lib/nodes/element/Element.js.map +1 -1
- package/lib/nodes/html-anchor-element/HTMLAnchorElement.d.ts +250 -0
- package/lib/nodes/html-anchor-element/HTMLAnchorElement.js +395 -0
- package/lib/nodes/html-anchor-element/HTMLAnchorElement.js.map +1 -0
- package/lib/nodes/html-anchor-element/HTMLAnchorElementUtility.d.ts +29 -0
- package/lib/nodes/html-anchor-element/HTMLAnchorElementUtility.js +45 -0
- package/lib/nodes/html-anchor-element/HTMLAnchorElementUtility.js.map +1 -0
- package/lib/nodes/html-anchor-element/IHTMLAnchorElement.d.ts +20 -0
- package/lib/nodes/html-anchor-element/IHTMLAnchorElement.js +3 -0
- package/lib/nodes/html-anchor-element/IHTMLAnchorElement.js.map +1 -0
- package/lib/nodes/html-anchor-element/IHTMLHyperlinkElementUtils.d.ts +19 -0
- package/lib/nodes/html-anchor-element/IHTMLHyperlinkElementUtils.js +3 -0
- package/lib/nodes/html-anchor-element/IHTMLHyperlinkElementUtils.js.map +1 -0
- package/lib/nodes/html-link-element/HTMLLinkElement.d.ts +3 -7
- package/lib/nodes/html-link-element/HTMLLinkElement.js +13 -13
- package/lib/nodes/html-link-element/HTMLLinkElement.js.map +1 -1
- package/lib/nodes/html-option-element/HTMLOptionElement.js +1 -1
- package/lib/nodes/html-option-element/HTMLOptionElement.js.map +1 -1
- package/package.json +2 -2
- package/src/config/ElementTag.ts +2 -1
- package/src/dom-token-list/DOMTokenList.ts +1 -1
- package/src/nodes/element/Element.ts +6 -11
- package/src/nodes/html-anchor-element/HTMLAnchorElement.ts +439 -0
- package/src/nodes/html-anchor-element/HTMLAnchorElementUtility.ts +48 -0
- package/src/nodes/html-anchor-element/IHTMLAnchorElement.ts +21 -0
- package/src/nodes/html-anchor-element/IHTMLHyperlinkElementUtils.ts +19 -0
- package/src/nodes/html-link-element/HTMLLinkElement.ts +18 -16
- package/src/nodes/html-option-element/HTMLOptionElement.ts +1 -1
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "happy-dom",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.7.0",
|
4
4
|
"license": "MIT",
|
5
5
|
"homepage": "https://github.com/capricorn86/happy-dom",
|
6
6
|
"repository": "https://github.com/capricorn86/happy-dom",
|
@@ -75,5 +75,5 @@
|
|
75
75
|
"ts-jest": "^27.1.3",
|
76
76
|
"typescript": "^4.6.2"
|
77
77
|
},
|
78
|
-
"gitHead": "
|
78
|
+
"gitHead": "9eb21a6f922278fe17ff2d4b99f2a2898fe2053f"
|
79
79
|
}
|
package/src/config/ElementTag.ts
CHANGED
@@ -20,9 +20,10 @@ import HTMLDialogElement from '../nodes/html-dialog-element/HTMLDialogElement';
|
|
20
20
|
import HTMLButtonElement from '../nodes/html-button-element/HTMLButtonElement';
|
21
21
|
import HTMLAudioElement from '../nodes/html-audio-element/HTMLAudioElement';
|
22
22
|
import HTMLVideoElement from '../nodes/html-video-element/HTMLVideoElement';
|
23
|
+
import HTMLAnchorElement from '../nodes/html-anchor-element/HTMLAnchorElement';
|
23
24
|
|
24
25
|
export default {
|
25
|
-
A:
|
26
|
+
A: HTMLAnchorElement,
|
26
27
|
ABBR: HTMLElement,
|
27
28
|
ADDRESS: HTMLElement,
|
28
29
|
AREA: HTMLElement,
|
@@ -199,7 +199,7 @@ export default class DOMTokenList implements IDOMTokenList {
|
|
199
199
|
* Updates indices.
|
200
200
|
*/
|
201
201
|
public _updateIndices(): void {
|
202
|
-
const attr = this._ownerElement.getAttribute(
|
202
|
+
const attr = this._ownerElement.getAttribute(this._attributeName);
|
203
203
|
const list = attr ? Array.from(new Set(attr.split(' '))) : [];
|
204
204
|
|
205
205
|
for (let i = list.length - 1, max = this.length; i < max; i++) {
|
@@ -840,7 +840,9 @@ export default class Element extends Node implements IElement {
|
|
840
840
|
|
841
841
|
this._attributes[name] = attribute;
|
842
842
|
|
843
|
-
this.
|
843
|
+
if (attribute.name === 'class' && this._classList) {
|
844
|
+
this._classList._updateIndices();
|
845
|
+
}
|
844
846
|
|
845
847
|
if (
|
846
848
|
this.attributeChangedCallback &&
|
@@ -936,7 +938,9 @@ export default class Element extends Node implements IElement {
|
|
936
938
|
this.ownerDocument['_cacheID']++;
|
937
939
|
}
|
938
940
|
|
939
|
-
this.
|
941
|
+
if (attribute.name === 'class' && this._classList) {
|
942
|
+
this._classList._updateIndices();
|
943
|
+
}
|
940
944
|
|
941
945
|
if (
|
942
946
|
this.attributeChangedCallback &&
|
@@ -1033,13 +1037,4 @@ export default class Element extends Node implements IElement {
|
|
1033
1037
|
}
|
1034
1038
|
return name.toLowerCase();
|
1035
1039
|
}
|
1036
|
-
|
1037
|
-
/**
|
1038
|
-
* Updates DOM list indices.
|
1039
|
-
*/
|
1040
|
-
protected _updateDomListIndices(): void {
|
1041
|
-
if (this._classList) {
|
1042
|
-
this._classList._updateIndices();
|
1043
|
-
}
|
1044
|
-
}
|
1045
1040
|
}
|
@@ -0,0 +1,439 @@
|
|
1
|
+
import HTMLElement from '../html-element/HTMLElement';
|
2
|
+
import DOMTokenList from '../../dom-token-list/DOMTokenList';
|
3
|
+
import IDOMTokenList from '../../dom-token-list/IDOMTokenList';
|
4
|
+
import IHTMLAnchorElement from './IHTMLAnchorElement';
|
5
|
+
import { URL } from 'url';
|
6
|
+
import IAttr from '../attr/IAttr';
|
7
|
+
import HTMLAnchorElementUtility from './HTMLAnchorElementUtility';
|
8
|
+
|
9
|
+
/**
|
10
|
+
* HTML Anchor Element.
|
11
|
+
*
|
12
|
+
* Reference:
|
13
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement.
|
14
|
+
*/
|
15
|
+
export default class HTMLAnchorElement extends HTMLElement implements IHTMLAnchorElement {
|
16
|
+
private _relList: DOMTokenList = null;
|
17
|
+
private _url: URL | null = null;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Returns download.
|
21
|
+
*
|
22
|
+
* @returns download.
|
23
|
+
*/
|
24
|
+
public get download(): string {
|
25
|
+
return this.getAttribute('download') || '';
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Sets download.
|
30
|
+
*
|
31
|
+
* @param download Download.
|
32
|
+
*/
|
33
|
+
public set download(download: string) {
|
34
|
+
this.setAttributeNS(null, 'download', download);
|
35
|
+
}
|
36
|
+
|
37
|
+
/**
|
38
|
+
* Returns hash.
|
39
|
+
*
|
40
|
+
* @returns Hash.
|
41
|
+
*/
|
42
|
+
public get hash(): string {
|
43
|
+
return this._url?.hash ?? '';
|
44
|
+
}
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Sets hash.
|
48
|
+
*
|
49
|
+
* @param hash Hash.
|
50
|
+
*/
|
51
|
+
public set hash(hash: string) {
|
52
|
+
if (this._url && !HTMLAnchorElementUtility.isBlobURL(this._url)) {
|
53
|
+
this._url.hash = hash;
|
54
|
+
this.setAttributeNS(null, 'href', this._url.toString());
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Returns href.
|
60
|
+
*
|
61
|
+
* @returns Href.
|
62
|
+
*/
|
63
|
+
public get href(): string | null {
|
64
|
+
if (this._url) {
|
65
|
+
return this._url.toString();
|
66
|
+
}
|
67
|
+
|
68
|
+
return this.getAttributeNS(null, 'href') || '';
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* Sets href.
|
73
|
+
*
|
74
|
+
* @param href Href.
|
75
|
+
*/
|
76
|
+
public set href(href: string) {
|
77
|
+
this.setAttributeNS(null, 'href', href);
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* Returns hreflang.
|
82
|
+
*
|
83
|
+
* @returns Hreflang.
|
84
|
+
*/
|
85
|
+
public get hreflang(): string {
|
86
|
+
return this.getAttributeNS(null, 'hreflang') || '';
|
87
|
+
}
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Sets hreflang.
|
91
|
+
*
|
92
|
+
* @param hreflang Hreflang.
|
93
|
+
*/
|
94
|
+
public set hreflang(hreflang: string) {
|
95
|
+
this.setAttributeNS(null, 'hreflang', hreflang);
|
96
|
+
}
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Returns the hyperlink's URL's origin.
|
100
|
+
*
|
101
|
+
* @returns Origin.
|
102
|
+
*/
|
103
|
+
public get origin(): string {
|
104
|
+
return this._url?.origin ?? '';
|
105
|
+
}
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Returns ping.
|
109
|
+
*
|
110
|
+
* @returns Ping.
|
111
|
+
*/
|
112
|
+
public get ping(): string {
|
113
|
+
return this.getAttributeNS(null, 'ping') || '';
|
114
|
+
}
|
115
|
+
|
116
|
+
/**
|
117
|
+
* Sets ping.
|
118
|
+
*
|
119
|
+
* @param ping Ping.
|
120
|
+
*/
|
121
|
+
public set ping(ping: string) {
|
122
|
+
this.setAttributeNS(null, 'ping', ping);
|
123
|
+
}
|
124
|
+
|
125
|
+
/**
|
126
|
+
* Returns protocol.
|
127
|
+
*
|
128
|
+
* @returns Protocol.
|
129
|
+
*/
|
130
|
+
public get protocol(): string {
|
131
|
+
return this._url?.protocol ?? '';
|
132
|
+
}
|
133
|
+
|
134
|
+
/**
|
135
|
+
* Sets protocol.
|
136
|
+
*
|
137
|
+
* @param protocol Protocol.
|
138
|
+
*/
|
139
|
+
public set protocol(protocol: string) {
|
140
|
+
if (this._url && !HTMLAnchorElementUtility.isBlobURL(this._url)) {
|
141
|
+
this._url.protocol = protocol;
|
142
|
+
this.setAttributeNS(null, 'href', this._url.toString());
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
/**
|
147
|
+
* Returns username.
|
148
|
+
*
|
149
|
+
* @returns Username.
|
150
|
+
*/
|
151
|
+
public get username(): string {
|
152
|
+
return this._url?.username ?? '';
|
153
|
+
}
|
154
|
+
|
155
|
+
/**
|
156
|
+
* Sets username.
|
157
|
+
*
|
158
|
+
* @param username Username.
|
159
|
+
*/
|
160
|
+
public set username(username: string) {
|
161
|
+
if (
|
162
|
+
this._url &&
|
163
|
+
!HTMLAnchorElementUtility.isBlobURL(this._url) &&
|
164
|
+
this._url.host &&
|
165
|
+
this._url.protocol != 'file'
|
166
|
+
) {
|
167
|
+
this._url.username = username;
|
168
|
+
this.setAttributeNS(null, 'href', this._url.toString());
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Returns password.
|
174
|
+
*
|
175
|
+
* @returns Password.
|
176
|
+
*/
|
177
|
+
public get password(): string {
|
178
|
+
return this._url?.password ?? '';
|
179
|
+
}
|
180
|
+
|
181
|
+
/**
|
182
|
+
* Sets password.
|
183
|
+
*
|
184
|
+
* @param password Password.
|
185
|
+
*/
|
186
|
+
public set password(password: string) {
|
187
|
+
if (
|
188
|
+
this._url &&
|
189
|
+
!HTMLAnchorElementUtility.isBlobURL(this._url) &&
|
190
|
+
this._url.host &&
|
191
|
+
this._url.protocol != 'file'
|
192
|
+
) {
|
193
|
+
this._url.password = password;
|
194
|
+
this.setAttributeNS(null, 'href', this._url.toString());
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
/**
|
199
|
+
* Returns pathname.
|
200
|
+
*
|
201
|
+
* @returns Pathname.
|
202
|
+
*/
|
203
|
+
public get pathname(): string {
|
204
|
+
return this._url?.pathname ?? '';
|
205
|
+
}
|
206
|
+
|
207
|
+
/**
|
208
|
+
* Sets pathname.
|
209
|
+
*
|
210
|
+
* @param pathname Pathname.
|
211
|
+
*/
|
212
|
+
public set pathname(pathname: string) {
|
213
|
+
if (this._url && !HTMLAnchorElementUtility.isBlobURL(this._url)) {
|
214
|
+
this._url.pathname = pathname;
|
215
|
+
this.setAttributeNS(null, 'href', this._url.toString());
|
216
|
+
}
|
217
|
+
}
|
218
|
+
|
219
|
+
/**
|
220
|
+
* Returns port.
|
221
|
+
*
|
222
|
+
* @returns Port.
|
223
|
+
*/
|
224
|
+
public get port(): string {
|
225
|
+
return this._url?.port ?? '';
|
226
|
+
}
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Sets port.
|
230
|
+
*
|
231
|
+
* @param port Port.
|
232
|
+
*/
|
233
|
+
public set port(port: string) {
|
234
|
+
if (
|
235
|
+
this._url &&
|
236
|
+
!HTMLAnchorElementUtility.isBlobURL(this._url) &&
|
237
|
+
this._url.host &&
|
238
|
+
this._url.protocol != 'file'
|
239
|
+
) {
|
240
|
+
this._url.port = port;
|
241
|
+
this.setAttributeNS(null, 'href', this._url.toString());
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
/**
|
246
|
+
* Returns host.
|
247
|
+
*
|
248
|
+
* @returns Host.
|
249
|
+
*/
|
250
|
+
public get host(): string {
|
251
|
+
return this._url?.host ?? '';
|
252
|
+
}
|
253
|
+
|
254
|
+
/**
|
255
|
+
* Sets host.
|
256
|
+
*
|
257
|
+
* @param host Host.
|
258
|
+
*/
|
259
|
+
public set host(host: string) {
|
260
|
+
if (this._url && !HTMLAnchorElementUtility.isBlobURL(this._url)) {
|
261
|
+
this._url.host = host;
|
262
|
+
this.setAttributeNS(null, 'href', this._url.toString());
|
263
|
+
}
|
264
|
+
}
|
265
|
+
|
266
|
+
/**
|
267
|
+
* Returns hostname.
|
268
|
+
*
|
269
|
+
* @returns Hostname.
|
270
|
+
*/
|
271
|
+
public get hostname(): string {
|
272
|
+
return this._url?.hostname ?? '';
|
273
|
+
}
|
274
|
+
|
275
|
+
/**
|
276
|
+
* Sets hostname.
|
277
|
+
*
|
278
|
+
* @param hostname Hostname.
|
279
|
+
*/
|
280
|
+
public set hostname(hostname: string) {
|
281
|
+
if (this._url && !HTMLAnchorElementUtility.isBlobURL(this._url)) {
|
282
|
+
this._url.hostname = hostname;
|
283
|
+
this.setAttributeNS(null, 'href', this._url.toString());
|
284
|
+
}
|
285
|
+
}
|
286
|
+
|
287
|
+
/**
|
288
|
+
* Returns referrerPolicy.
|
289
|
+
*
|
290
|
+
* @returns Referrer Policy.
|
291
|
+
*/
|
292
|
+
public get referrerPolicy(): string {
|
293
|
+
return this.getAttributeNS(null, 'referrerPolicy') || '';
|
294
|
+
}
|
295
|
+
|
296
|
+
/**
|
297
|
+
* Sets referrerPolicy.
|
298
|
+
*
|
299
|
+
* @param referrerPolicy Referrer Policy.
|
300
|
+
*/
|
301
|
+
public set referrerPolicy(referrerPolicy: string) {
|
302
|
+
this.setAttributeNS(null, 'referrerPolicy', referrerPolicy);
|
303
|
+
}
|
304
|
+
|
305
|
+
/**
|
306
|
+
* Returns rel.
|
307
|
+
*
|
308
|
+
* @returns Rel.
|
309
|
+
*/
|
310
|
+
public get rel(): string {
|
311
|
+
return this.getAttributeNS(null, 'rel') || '';
|
312
|
+
}
|
313
|
+
|
314
|
+
/**
|
315
|
+
* Sets rel.
|
316
|
+
*
|
317
|
+
* @param rel Rel.
|
318
|
+
*/
|
319
|
+
public set rel(rel: string) {
|
320
|
+
this.setAttributeNS(null, 'rel', rel);
|
321
|
+
}
|
322
|
+
|
323
|
+
/**
|
324
|
+
* Returns rel list.
|
325
|
+
*
|
326
|
+
* @returns Rel list.
|
327
|
+
*/
|
328
|
+
public get relList(): IDOMTokenList {
|
329
|
+
if (!this._relList) {
|
330
|
+
this._relList = new DOMTokenList(this, 'rel');
|
331
|
+
}
|
332
|
+
return <IDOMTokenList>this._relList;
|
333
|
+
}
|
334
|
+
|
335
|
+
/**
|
336
|
+
* Returns search.
|
337
|
+
*
|
338
|
+
* @returns Search.
|
339
|
+
*/
|
340
|
+
public get search(): string {
|
341
|
+
return this._url?.search ?? '';
|
342
|
+
}
|
343
|
+
|
344
|
+
/**
|
345
|
+
* Sets search.
|
346
|
+
*
|
347
|
+
* @param search Search.
|
348
|
+
*/
|
349
|
+
public set search(search: string) {
|
350
|
+
if (this._url && !HTMLAnchorElementUtility.isBlobURL(this._url)) {
|
351
|
+
this._url.search = search;
|
352
|
+
this.setAttributeNS(null, 'href', this._url.toString());
|
353
|
+
}
|
354
|
+
}
|
355
|
+
|
356
|
+
/**
|
357
|
+
* Returns target.
|
358
|
+
*
|
359
|
+
* @returns target.
|
360
|
+
*/
|
361
|
+
public get target(): string {
|
362
|
+
return this.getAttributeNS(null, 'target') || '';
|
363
|
+
}
|
364
|
+
|
365
|
+
/**
|
366
|
+
* Sets target.
|
367
|
+
*
|
368
|
+
* @param target Target.
|
369
|
+
*/
|
370
|
+
public set target(target: string) {
|
371
|
+
this.setAttributeNS(null, 'target', target);
|
372
|
+
}
|
373
|
+
|
374
|
+
/**
|
375
|
+
* Returns text.
|
376
|
+
*
|
377
|
+
* @returns text.
|
378
|
+
*/
|
379
|
+
public get text(): string {
|
380
|
+
return this.textContent;
|
381
|
+
}
|
382
|
+
|
383
|
+
/**
|
384
|
+
* Sets text.
|
385
|
+
*
|
386
|
+
* @param text Text.
|
387
|
+
*/
|
388
|
+
public set text(text: string) {
|
389
|
+
this.textContent = text;
|
390
|
+
}
|
391
|
+
|
392
|
+
/**
|
393
|
+
* Returns type.
|
394
|
+
*
|
395
|
+
* @returns Type.
|
396
|
+
*/
|
397
|
+
public get type(): string {
|
398
|
+
return this.getAttributeNS(null, 'type') || '';
|
399
|
+
}
|
400
|
+
|
401
|
+
/**
|
402
|
+
* Sets type.
|
403
|
+
*
|
404
|
+
* @param type Type.
|
405
|
+
*/
|
406
|
+
public set type(type: string) {
|
407
|
+
this.setAttributeNS(null, 'type', type);
|
408
|
+
}
|
409
|
+
|
410
|
+
/**
|
411
|
+
* @override
|
412
|
+
*/
|
413
|
+
public override setAttributeNode(attribute: IAttr): IAttr {
|
414
|
+
const replacedAttribute = super.setAttributeNode(attribute);
|
415
|
+
|
416
|
+
if (attribute.name === 'rel' && this._relList) {
|
417
|
+
this._relList._updateIndices();
|
418
|
+
} else if (attribute.name === 'href') {
|
419
|
+
this._url = HTMLAnchorElementUtility.getUrl(this.ownerDocument, attribute.value);
|
420
|
+
}
|
421
|
+
|
422
|
+
return replacedAttribute;
|
423
|
+
}
|
424
|
+
|
425
|
+
/**
|
426
|
+
* @override
|
427
|
+
*/
|
428
|
+
public override removeAttributeNode(attribute: IAttr): IAttr {
|
429
|
+
super.removeAttributeNode(attribute);
|
430
|
+
|
431
|
+
if (attribute.name === 'rel' && this._relList) {
|
432
|
+
this._relList._updateIndices();
|
433
|
+
} else if (attribute.name === 'href') {
|
434
|
+
this._url = null;
|
435
|
+
}
|
436
|
+
|
437
|
+
return attribute;
|
438
|
+
}
|
439
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import IDocument from '../document/IDocument';
|
2
|
+
import { URL } from 'url';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* HTML Anchor Element utility.
|
6
|
+
*/
|
7
|
+
export default class HTMLAnchorElementUtility {
|
8
|
+
/**
|
9
|
+
* Returns "true" if it is a blob URL.
|
10
|
+
*
|
11
|
+
* According to spec, if element's url is non-null, its scheme is "blob", and it has an opaque path, then the process of updating properties on the URL should be terminated.
|
12
|
+
*
|
13
|
+
* @see https://html.spec.whatwg.org/multipage/links.html#reinitialise-url
|
14
|
+
* @param url
|
15
|
+
* @param url URL.
|
16
|
+
* @returns "true" if blob URL.
|
17
|
+
*/
|
18
|
+
public static isBlobURL(url: URL): boolean {
|
19
|
+
return (
|
20
|
+
url && url.protocol === 'blob:' && url.pathname.length > 1 && url.pathname.includes('://')
|
21
|
+
);
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* Returns URL.
|
26
|
+
*
|
27
|
+
* @see https://html.spec.whatwg.org/multipage/links.html#dom-hyperlink-href
|
28
|
+
* @see https://html.spec.whatwg.org/multipage/links.html#hyperlink
|
29
|
+
* @param document Document.
|
30
|
+
* @param href Href.
|
31
|
+
* @returns URL.
|
32
|
+
*/
|
33
|
+
public static getUrl(document: IDocument, href: string | null): URL {
|
34
|
+
if (!href) {
|
35
|
+
return null;
|
36
|
+
}
|
37
|
+
|
38
|
+
const documentUrl = document.location.href;
|
39
|
+
|
40
|
+
try {
|
41
|
+
return new URL(href.trim(), documentUrl);
|
42
|
+
} catch (TypeError) {
|
43
|
+
// Ignore error
|
44
|
+
}
|
45
|
+
|
46
|
+
return null;
|
47
|
+
}
|
48
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import IDOMTokenList from '../../dom-token-list/IDOMTokenList';
|
2
|
+
import IHTMLElement from '../html-element/IHTMLElement';
|
3
|
+
import IHTMLHyperlinkElementUtils from './IHTMLHyperlinkElementUtils';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* HTML Anchor Element.
|
7
|
+
*
|
8
|
+
* Reference:
|
9
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement.
|
10
|
+
*/
|
11
|
+
export default interface IHTMLAnchorElement extends IHTMLElement, IHTMLHyperlinkElementUtils {
|
12
|
+
readonly relList: IDOMTokenList;
|
13
|
+
download: string;
|
14
|
+
ping: string;
|
15
|
+
hreflang: string;
|
16
|
+
referrerPolicy: string;
|
17
|
+
rel: string;
|
18
|
+
target: string;
|
19
|
+
text: string;
|
20
|
+
type: string;
|
21
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
/**
|
2
|
+
* HTMLHyperlinkElementUtils.
|
3
|
+
*
|
4
|
+
* Reference:
|
5
|
+
* https://html.spec.whatwg.org/multipage/links.html#htmlhyperlinkelementutils.
|
6
|
+
*/
|
7
|
+
export default interface IHTMLHyperlinkElementUtils {
|
8
|
+
readonly origin: string;
|
9
|
+
href: string;
|
10
|
+
protocol: string;
|
11
|
+
username: string;
|
12
|
+
password: string;
|
13
|
+
host: string;
|
14
|
+
hostname: string;
|
15
|
+
port: string;
|
16
|
+
pathname: string;
|
17
|
+
search: string;
|
18
|
+
hash: string;
|
19
|
+
}
|
@@ -180,17 +180,17 @@ export default class HTMLLinkElement extends HTMLElement implements IHTMLLinkEle
|
|
180
180
|
}
|
181
181
|
|
182
182
|
/**
|
183
|
-
* The setAttributeNode() method adds a new Attr node to the specified element.
|
184
|
-
*
|
185
183
|
* @override
|
186
|
-
* @param attribute Attribute.
|
187
|
-
* @returns Replaced attribute.
|
188
184
|
*/
|
189
|
-
public setAttributeNode(attribute: IAttr): IAttr {
|
185
|
+
public override setAttributeNode(attribute: IAttr): IAttr {
|
190
186
|
const replacedAttribute = super.setAttributeNode(attribute);
|
191
187
|
const rel = this.getAttributeNS(null, 'rel');
|
192
188
|
const href = this.getAttributeNS(null, 'href');
|
193
189
|
|
190
|
+
if (attribute.name === 'rel' && this._relList) {
|
191
|
+
this._relList._updateIndices();
|
192
|
+
}
|
193
|
+
|
194
194
|
if (
|
195
195
|
(attribute.name === 'rel' || attribute.name === 'href') &&
|
196
196
|
href !== null &&
|
@@ -233,6 +233,19 @@ export default class HTMLLinkElement extends HTMLElement implements IHTMLLinkEle
|
|
233
233
|
return replacedAttribute;
|
234
234
|
}
|
235
235
|
|
236
|
+
/**
|
237
|
+
* @override
|
238
|
+
*/
|
239
|
+
public override removeAttributeNode(attribute: IAttr): IAttr {
|
240
|
+
super.removeAttributeNode(attribute);
|
241
|
+
|
242
|
+
if (attribute.name === 'rel' && this._relList) {
|
243
|
+
this._relList._updateIndices();
|
244
|
+
}
|
245
|
+
|
246
|
+
return attribute;
|
247
|
+
}
|
248
|
+
|
236
249
|
/**
|
237
250
|
* @override
|
238
251
|
*/
|
@@ -280,15 +293,4 @@ export default class HTMLLinkElement extends HTMLElement implements IHTMLLinkEle
|
|
280
293
|
}
|
281
294
|
}
|
282
295
|
}
|
283
|
-
|
284
|
-
/**
|
285
|
-
* Updates DOM list indices.
|
286
|
-
*/
|
287
|
-
protected _updateDomListIndices(): void {
|
288
|
-
super._updateDomListIndices();
|
289
|
-
|
290
|
-
if (this._relList) {
|
291
|
-
this._relList._updateIndices();
|
292
|
-
}
|
293
|
-
}
|
294
296
|
}
|
@@ -109,7 +109,7 @@ export default class HTMLOptionElement extends HTMLElement implements IHTMLOptio
|
|
109
109
|
* @returns Value.
|
110
110
|
*/
|
111
111
|
public get value(): string {
|
112
|
-
return this.getAttributeNS(null, 'value') ||
|
112
|
+
return this.getAttributeNS(null, 'value') || this.textContent;
|
113
113
|
}
|
114
114
|
|
115
115
|
/**
|