Skip to content

Commit a2f3a48

Browse files
authored
feat(axe.d.ts): add nodeSerializer typings (#4551)
This API was added in pr #4093, but TS definitions were never added. For simplicity I'm using SerialDqElement in the API. We could introduce a generic for the custom serialized type (T extends SerialDqElement), but it's hard to consistently use it everywhere (AxeReporter, NodeSerializer.dqElmToSpec). I also fixed DqElement.mergeSpecs which is needed to implement a custom node serializer: it exists on the constructor and not on the individual instances
1 parent b422c79 commit a2f3a48

2 files changed

Lines changed: 36 additions & 4 deletions

File tree

axe.d.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ declare namespace axe {
342342
interface DqElement extends SerialDqElement {
343343
element: Element;
344344
toJSON(): SerialDqElement;
345+
}
346+
interface DqElementConstructor {
347+
new (elm: Element, options?: { absolutePaths?: boolean }): DqElement;
345348
mergeSpecs(
346349
childSpec: SerialDqElement,
347350
parentSpec: SerialDqElement
@@ -405,6 +408,24 @@ declare namespace axe {
405408
boundingClientRect: DOMRect;
406409
}
407410

411+
interface CustomNodeSerializer<T = SerialDqElement> {
412+
toSpec: (dqElm: DqElement) => T;
413+
mergeSpecs: (nodeSpec: T, parentFrameSpec: T) => T;
414+
}
415+
416+
interface NodeSerializer {
417+
update: <T>(serializer: CustomNodeSerializer<T>) => void;
418+
toSpec: (node: Element | VirtualNode) => SerialDqElement;
419+
dqElmToSpec: (
420+
dqElm: DqElement | SerialDqElement,
421+
options?: RunOptions
422+
) => SerialDqElement;
423+
mergeSpecs: (
424+
nodeSpec: SerialDqElement,
425+
parentFrameSpec: SerialDqElement
426+
) => SerialDqElement;
427+
}
428+
408429
interface Utils {
409430
getFrameContexts: (
410431
context?: ElementContext,
@@ -423,15 +444,13 @@ declare namespace axe {
423444
selector: unknown
424445
) => selector is LabelledShadowDomSelector;
425446

426-
DqElement: new (
427-
elm: Element,
428-
options?: { absolutePaths?: boolean }
429-
) => DqElement;
447+
DqElement: DqElementConstructor;
430448
uuid: (
431449
options?: { random?: Uint8Array | Array<number> },
432450
buf?: Uint8Array | Array<number>,
433451
offset?: number
434452
) => string | Uint8Array | Array<number>;
453+
nodeSerializer: NodeSerializer;
435454
}
436455

437456
interface Aria {

typings/axe-core/axe-core-tests.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,19 @@ if (axe.utils.isLabelledShadowDomSelector(unknownContext)) {
450450
} else if (axe.utils.isContextSpec(unknownContext)) {
451451
let context: axe.ContextSpec = unknownContext;
452452
}
453+
axe.utils.nodeSerializer.update({
454+
toSpec(dqElm: axe.DqElement) {
455+
return dqElm.toJSON();
456+
},
457+
mergeSpecs(childSpec: axe.SerialDqElement, parentSpec: axe.SerialDqElement) {
458+
return axe.utils.DqElement.mergeSpecs(childSpec, parentSpec);
459+
}
460+
});
461+
const spec2: axe.SerialDqElement = axe.utils.nodeSerializer.toSpec(element);
462+
const spec3: axe.SerialDqElement = axe.utils.nodeSerializer.dqElmToSpec(
463+
dqElement,
464+
options
465+
);
453466

454467
// Commons
455468
axe.commons.aria.getRoleType('img');

0 commit comments

Comments
 (0)