@siteimprove/alfa-dom 0.101.0 → 0.102.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @siteimprove/alfa-dom
2
2
 
3
+ ## 0.102.0
4
+
5
+ ### Minor Changes
6
+
7
+ - **Added:** `Native.fromNode` returned value now contains a `logs` field, with an array of logs. ([#1781](https://github.com/Siteimprove/alfa/pull/1781))
8
+
9
+ - **Breaking:** The `withCrossOrigin` option of `dom.Native.fromNode` has been renamed `ensureAnonymousCrossOrigin`. ([#1779](https://github.com/Siteimprove/alfa/pull/1779))
10
+
11
+ The old `withCrossOrigin` option is kept as a deprecated legacy alias and will be removed in a later release.
12
+
13
+ The new name better reflects the meaning of the option.
14
+
3
15
  ## 0.101.0
4
16
 
5
17
  ## 0.100.1
package/dist/native.d.ts CHANGED
@@ -1,18 +1,43 @@
1
1
  import type { Attribute, Comment, Document, Element, Node, Text, Type } from "./index.js";
2
+ /**
3
+ * The type of logs.
4
+ *
5
+ * @remarks
6
+ * Each log entry **should** be a JSON stringified object of type
7
+ * \{ level: "debug" | "info" | "warn" | "error", type: string, message: string \}
8
+ * Different types may add more fields to the object.
9
+ *
10
+ * @privateRemarks
11
+ * Given that everything is inlined in one function, it is easier to have a
12
+ * "global" logs array and add to it from any subfunction, rather than merging
13
+ * logs from these.
14
+ */
15
+ type Logs = {
16
+ logs: Array<string>;
17
+ };
2
18
  /**
3
19
  * @internal
4
20
  */
5
21
  export declare namespace Native {
6
- function fromNode(node: globalThis.Element, options?: Options): Promise<Element.JSON>;
7
- function fromNode(node: globalThis.Attr, options?: Options): Promise<Attribute.JSON>;
8
- function fromNode(node: globalThis.Text, options?: Options): Promise<Text.JSON>;
9
- function fromNode(node: globalThis.Comment, options?: Options): Promise<Comment.JSON>;
10
- function fromNode(node?: globalThis.Document, options?: Options): Promise<Document.JSON>;
11
- function fromNode(node: globalThis.DocumentType, options?: Options): Promise<Type.JSON>;
12
- function fromNode(node: globalThis.Node, options?: Options): Promise<Node.JSON>;
22
+ function fromNode(node: globalThis.Element, options?: Options): Promise<Element.JSON & Logs>;
23
+ function fromNode(node: globalThis.Attr, options?: Options): Promise<Attribute.JSON & Logs>;
24
+ function fromNode(node: globalThis.Text, options?: Options): Promise<Text.JSON & Logs>;
25
+ function fromNode(node: globalThis.Comment, options?: Options): Promise<Comment.JSON & Logs>;
26
+ function fromNode(node?: globalThis.Document, options?: Options): Promise<Document.JSON & Logs>;
27
+ function fromNode(node: globalThis.DocumentType, options?: Options): Promise<Type.JSON & Logs>;
28
+ function fromNode(node: globalThis.Node, options?: Options): Promise<Node.JSON & Logs>;
13
29
  interface Options {
14
- /** Whether to enforce anonymous CORS on <link> missing one */
30
+ /**
31
+ * Deprecated, use enforceAnonymousCrossOrigin instead
32
+ *
33
+ * @deprecated
34
+ */
15
35
  withCrossOrigin?: boolean;
36
+ /**
37
+ * Whether to enforce anonymous crossorigin attribute on <link> missing one
38
+ */
39
+ enforceAnonymousCrossOrigin?: boolean;
16
40
  }
17
41
  }
42
+ export {};
18
43
  //# sourceMappingURL=native.d.ts.map
package/dist/native.js CHANGED
@@ -5,9 +5,10 @@
5
5
  export var Native;
6
6
  (function (Native) {
7
7
  async function fromNode(node = globalThis.window.document, options) {
8
- const { withCrossOrigin = false } = options ?? {};
8
+ const logs = [];
9
+ const { withCrossOrigin = false, enforceAnonymousCrossOrigin = withCrossOrigin, } = options ?? {};
9
10
  const range = globalThis.document.createRange(); // Used by toText - the same instance can be reused for each text node.
10
- return toNode(node);
11
+ return { ...(await toNode(node)), logs };
11
12
  async function toNode(node) {
12
13
  switch (node.nodeType) {
13
14
  case node.ELEMENT_NODE:
@@ -72,7 +73,7 @@ export var Native;
72
73
  };
73
74
  }
74
75
  async function toDocument(document) {
75
- if (withCrossOrigin) {
76
+ if (enforceAnonymousCrossOrigin) {
76
77
  await ensureCrossOrigin(document);
77
78
  }
78
79
  return {
@@ -90,7 +91,7 @@ export var Native;
90
91
  };
91
92
  }
92
93
  async function toShadow(shadow) {
93
- if (withCrossOrigin) {
94
+ if (enforceAnonymousCrossOrigin) {
94
95
  await ensureCrossOrigin(document);
95
96
  }
96
97
  return {
@@ -230,14 +231,36 @@ export var Native;
230
231
  };
231
232
  }
232
233
  function toImportRule(rule) {
233
- return {
234
- type: "import",
235
- rules: rule.styleSheet === null ? [] : toSheet(rule.styleSheet).rules,
236
- condition: rule.media.mediaText === "" ? "all" : rule.media.mediaText,
237
- href: rule.href,
238
- supportText: rule.supportsText,
239
- layer: rule.layerName,
240
- };
234
+ try {
235
+ // See https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet#instance_properties
236
+ // While the error may theoretically occur on any style sheet, it seems
237
+ // to be mostly present on @import rules due to CORS policy.
238
+ rule.styleSheet?.cssRules;
239
+ return {
240
+ type: "import",
241
+ rules: rule.styleSheet === null ? [] : toSheet(rule.styleSheet).rules,
242
+ condition: rule.media.mediaText === "" ? "all" : rule.media.mediaText,
243
+ href: rule.href,
244
+ supportText: rule.supportsText,
245
+ layer: rule.layerName,
246
+ };
247
+ }
248
+ catch (e) {
249
+ logs.push(JSON.stringify({
250
+ level: "error",
251
+ type: "import",
252
+ message: `Failed to fetch CSS rules for @import rule at ${rule.href}`,
253
+ originalError: `${e}`,
254
+ }));
255
+ return {
256
+ type: "import",
257
+ rules: [],
258
+ condition: rule.media.mediaText === "" ? "all" : rule.media.mediaText,
259
+ href: rule.href,
260
+ supportText: rule.supportsText,
261
+ layer: rule.layerName,
262
+ };
263
+ }
241
264
  }
242
265
  function toKeyframeRule(rule) {
243
266
  return {
@@ -335,8 +358,8 @@ export var Native;
335
358
  *
336
359
  * {@link https://github.com/Siteimprove/alfa/issues/1563}
337
360
  *
338
- * To circumvent that, we simply return the raw CSS text; and delegate parsing
339
- * to consumers, aka Block.from.
361
+ * To circumvent that, we simply return the raw CSS text; and delegate
362
+ * parsing to consumers, aka Block.from.
340
363
  *
341
364
  * Note that somehow JSDOM behaves differently and correctly associate the
342
365
  * value with the shorthand. This means that the local tests using JSDOM
@@ -386,8 +409,8 @@ export var Native;
386
409
  for (let i = 0; i < links.length; i++) {
387
410
  const link = links[i];
388
411
  /**
389
- * Skip `<link>` elements for which the `crossorigin` attribute is already
390
- * set to a valid value.
412
+ * Skip `<link>` elements for which the `crossorigin` attribute is
413
+ * already set to a valid value.
391
414
  */
392
415
  if (link.crossOrigin !== null) {
393
416
  continue;
@@ -406,25 +429,25 @@ export var Native;
406
429
  */
407
430
  clone.crossOrigin = "anonymous";
408
431
  /**
409
- * Replace the original `<link>` element with its clone. For style sheets,
410
- * this will unfortunately cause a FOUC while the browser recomputes
411
- * styles.
432
+ * Replace the original `<link>` element with its clone. For style
433
+ * sheets, this will unfortunately cause a FOUC while the browser
434
+ * recomputes styles.
412
435
  *
413
436
  * {@link https://en.wikipedia.org/wiki/Flash_of_unstyled_content}
414
437
  */
415
438
  link.parentNode.replaceChild(clone, link);
416
439
  /**
417
- * While certain resources will load synchronously from cache, others will
418
- * not and we therefore need to await these.
440
+ * While certain resources will load synchronously from cache, others
441
+ * will not and we therefore need to await these.
419
442
  */
420
443
  if (shouldAwait(link)) {
421
444
  /**
422
445
  * Construct a promise that resolves once the `<link>` element either
423
- * loads successfully or fails to load. If the `<link>` element fails to
424
- * load, a request error will be logged to the console which should be
425
- * enough indication that something didn't go quite as expected. Either
426
- * way, we will deliver audit results even in the event of a missing
427
- * resource.
446
+ * loads successfully or fails to load. If the `<link>` element fails
447
+ * to load, a request error will be logged to the console which
448
+ * should be enough indication that something didn't go quite as
449
+ * expected. Either way, we will deliver audit results even in the
450
+ * event of a missing resource.
428
451
  */
429
452
  await new Promise((resolve) => ["load", "error"].forEach((event) => clone.addEventListener(event, () => resolve())));
430
453
  }
@@ -434,8 +457,8 @@ export var Native;
434
457
  */
435
458
  function shouldAwait(link) {
436
459
  /**
437
- * A `<link>` element with an empty `href` will cause the fetch process to
438
- * abort with no events to await.
460
+ * A `<link>` element with an empty `href` will cause the fetch process
461
+ * to abort with no events to await.
439
462
  */
440
463
  if (link.getAttribute("href")?.trim() === "") {
441
464
  return false;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "http://json.schemastore.org/package",
3
3
  "name": "@siteimprove/alfa-dom",
4
4
  "homepage": "https://alfa.siteimprove.com",
5
- "version": "0.101.0",
5
+ "version": "0.102.0",
6
6
  "license": "MIT",
7
7
  "description": "Implementations of the core DOM and CSSOM node types",
8
8
  "repository": {
@@ -35,35 +35,35 @@
35
35
  "dist/**/*.d.ts"
36
36
  ],
37
37
  "dependencies": {
38
- "@siteimprove/alfa-array": "^0.101.0",
39
- "@siteimprove/alfa-cache": "^0.101.0",
40
- "@siteimprove/alfa-comparable": "^0.101.0",
41
- "@siteimprove/alfa-css": "^0.101.0",
42
- "@siteimprove/alfa-css-feature": "^0.101.0",
43
- "@siteimprove/alfa-device": "^0.101.0",
44
- "@siteimprove/alfa-earl": "^0.101.0",
45
- "@siteimprove/alfa-equatable": "^0.101.0",
46
- "@siteimprove/alfa-flags": "^0.101.0",
47
- "@siteimprove/alfa-iterable": "^0.101.0",
48
- "@siteimprove/alfa-json": "^0.101.0",
49
- "@siteimprove/alfa-lazy": "^0.101.0",
50
- "@siteimprove/alfa-map": "^0.101.0",
51
- "@siteimprove/alfa-option": "^0.101.0",
52
- "@siteimprove/alfa-parser": "^0.101.0",
53
- "@siteimprove/alfa-predicate": "^0.101.0",
54
- "@siteimprove/alfa-rectangle": "^0.101.0",
55
- "@siteimprove/alfa-refinement": "^0.101.0",
56
- "@siteimprove/alfa-result": "^0.101.0",
57
- "@siteimprove/alfa-sarif": "^0.101.0",
58
- "@siteimprove/alfa-selective": "^0.101.0",
59
- "@siteimprove/alfa-sequence": "^0.101.0",
60
- "@siteimprove/alfa-slice": "^0.101.0",
61
- "@siteimprove/alfa-string": "^0.101.0",
62
- "@siteimprove/alfa-trampoline": "^0.101.0",
63
- "@siteimprove/alfa-tree": "^0.101.0"
38
+ "@siteimprove/alfa-array": "^0.102.0",
39
+ "@siteimprove/alfa-cache": "^0.102.0",
40
+ "@siteimprove/alfa-comparable": "^0.102.0",
41
+ "@siteimprove/alfa-css": "^0.102.0",
42
+ "@siteimprove/alfa-css-feature": "^0.102.0",
43
+ "@siteimprove/alfa-device": "^0.102.0",
44
+ "@siteimprove/alfa-earl": "^0.102.0",
45
+ "@siteimprove/alfa-equatable": "^0.102.0",
46
+ "@siteimprove/alfa-flags": "^0.102.0",
47
+ "@siteimprove/alfa-iterable": "^0.102.0",
48
+ "@siteimprove/alfa-json": "^0.102.0",
49
+ "@siteimprove/alfa-lazy": "^0.102.0",
50
+ "@siteimprove/alfa-map": "^0.102.0",
51
+ "@siteimprove/alfa-option": "^0.102.0",
52
+ "@siteimprove/alfa-parser": "^0.102.0",
53
+ "@siteimprove/alfa-predicate": "^0.102.0",
54
+ "@siteimprove/alfa-rectangle": "^0.102.0",
55
+ "@siteimprove/alfa-refinement": "^0.102.0",
56
+ "@siteimprove/alfa-result": "^0.102.0",
57
+ "@siteimprove/alfa-sarif": "^0.102.0",
58
+ "@siteimprove/alfa-selective": "^0.102.0",
59
+ "@siteimprove/alfa-sequence": "^0.102.0",
60
+ "@siteimprove/alfa-slice": "^0.102.0",
61
+ "@siteimprove/alfa-string": "^0.102.0",
62
+ "@siteimprove/alfa-trampoline": "^0.102.0",
63
+ "@siteimprove/alfa-tree": "^0.102.0"
64
64
  },
65
65
  "devDependencies": {
66
- "@siteimprove/alfa-test": "^0.101.0",
66
+ "@siteimprove/alfa-test": "^0.102.0",
67
67
  "@types/jsdom": "^21.1.6",
68
68
  "jsdom": "^26.0.0"
69
69
  },