Skip to content

Commit

Permalink
feat(axe.d.ts): add nodeSerializer typings (#4551)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
hamax committed Sep 24, 2024
1 parent b422c79 commit a2f3a48
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
27 changes: 23 additions & 4 deletions axe.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,9 @@ declare namespace axe {
interface DqElement extends SerialDqElement {
element: Element;
toJSON(): SerialDqElement;
}
interface DqElementConstructor {
new (elm: Element, options?: { absolutePaths?: boolean }): DqElement;
mergeSpecs(
childSpec: SerialDqElement,
parentSpec: SerialDqElement
Expand Down Expand Up @@ -405,6 +408,24 @@ declare namespace axe {
boundingClientRect: DOMRect;
}

interface CustomNodeSerializer<T = SerialDqElement> {
toSpec: (dqElm: DqElement) => T;
mergeSpecs: (nodeSpec: T, parentFrameSpec: T) => T;
}

interface NodeSerializer {
update: <T>(serializer: CustomNodeSerializer<T>) => void;
toSpec: (node: Element | VirtualNode) => SerialDqElement;
dqElmToSpec: (
dqElm: DqElement | SerialDqElement,
options?: RunOptions
) => SerialDqElement;
mergeSpecs: (
nodeSpec: SerialDqElement,
parentFrameSpec: SerialDqElement
) => SerialDqElement;
}

interface Utils {
getFrameContexts: (
context?: ElementContext,
Expand All @@ -423,15 +444,13 @@ declare namespace axe {
selector: unknown
) => selector is LabelledShadowDomSelector;

DqElement: new (
elm: Element,
options?: { absolutePaths?: boolean }
) => DqElement;
DqElement: DqElementConstructor;
uuid: (
options?: { random?: Uint8Array | Array<number> },
buf?: Uint8Array | Array<number>,
offset?: number
) => string | Uint8Array | Array<number>;
nodeSerializer: NodeSerializer;
}

interface Aria {
Expand Down
13 changes: 13 additions & 0 deletions typings/axe-core/axe-core-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,19 @@ if (axe.utils.isLabelledShadowDomSelector(unknownContext)) {
} else if (axe.utils.isContextSpec(unknownContext)) {
let context: axe.ContextSpec = unknownContext;
}
axe.utils.nodeSerializer.update({
toSpec(dqElm: axe.DqElement) {
return dqElm.toJSON();
},
mergeSpecs(childSpec: axe.SerialDqElement, parentSpec: axe.SerialDqElement) {
return axe.utils.DqElement.mergeSpecs(childSpec, parentSpec);
}
});
const spec2: axe.SerialDqElement = axe.utils.nodeSerializer.toSpec(element);
const spec3: axe.SerialDqElement = axe.utils.nodeSerializer.dqElmToSpec(
dqElement,
options
);

// Commons
axe.commons.aria.getRoleType('img');
Expand Down

0 comments on commit a2f3a48

Please sign in to comment.