From 63a2c673b53710694361105e900663112d706d55 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Tue, 18 Aug 2020 20:25:03 -0700 Subject: [PATCH] chore: align SerializedAXNode with rpc protocol AXNode (#3522) --- src/chromium/crAccessibility.ts | 33 ++++++++++++++------------------ src/firefox/ffAccessibility.ts | 22 +++++++++------------ src/rpc/server/pageDispatcher.ts | 17 ++-------------- src/types.ts | 7 ++++--- src/webkit/wkAccessibility.ts | 24 +++++++++++------------ 5 files changed, 41 insertions(+), 62 deletions(-) diff --git a/src/chromium/crAccessibility.ts b/src/chromium/crAccessibility.ts index b5eba7ab65..de94f274d2 100644 --- a/src/chromium/crAccessibility.ts +++ b/src/chromium/crAccessibility.ts @@ -203,20 +203,15 @@ class CRAXNode implements accessibility.AXNode { const properties: Map = new Map(); for (const property of this._payload.properties || []) properties.set(property.name.toLowerCase(), property.value.value); - if (this._payload.name) - properties.set('name', this._payload.name.value); - if (this._payload.value) - properties.set('value', this._payload.value.value); if (this._payload.description) properties.set('description', this._payload.description.value); const node: {[x in keyof types.SerializedAXNode]: any} = { role: this._role, - name: this._payload.name ? (this._payload.name.value || '') : '' + name: this._payload.name ? (this._payload.name.value || '') : '', }; const userStringProperties: Array = [ - 'value', 'description', 'keyshortcuts', 'roledescription', @@ -227,7 +222,6 @@ class CRAXNode implements accessibility.AXNode { continue; node[userStringProperty] = properties.get(userStringProperty); } - const booleanProperties: Array = [ 'disabled', 'expanded', @@ -249,17 +243,6 @@ class CRAXNode implements accessibility.AXNode { continue; node[booleanProperty] = value; } - - const tristateProperties: Array = [ - 'checked', - 'pressed', - ]; - for (const tristateProperty of tristateProperties) { - if (!properties.has(tristateProperty)) - continue; - const value = properties.get(tristateProperty); - node[tristateProperty] = value === 'mixed' ? 'mixed' : value === 'true' ? true : false; - } const numericalProperties: Array = [ 'level', 'valuemax', @@ -282,7 +265,19 @@ class CRAXNode implements accessibility.AXNode { continue; node[tokenProperty] = value; } - return node as types.SerializedAXNode; + + const axNode = node as types.SerializedAXNode; + if (this._payload.value) { + if (typeof this._payload.value.value === 'string') + axNode.valueString = this._payload.value.value; + if (typeof this._payload.value.value === 'number') + axNode.valueNumber = this._payload.value.value; + } + if (properties.has('checked')) + axNode.checked = properties.get('checked') === 'true' ? 'checked' : properties.get('checked') === 'false' ? 'unchecked' : 'mixed'; + if (properties.has('pressed')) + axNode.pressed = properties.get('pressed') === 'true' ? 'pressed' : properties.get('pressed') === 'false' ? 'released' : 'mixed'; + return axNode; } static createTree(client: CRSession, payloads: Protocol.Accessibility.AXNode[]): CRAXNode { diff --git a/src/firefox/ffAccessibility.ts b/src/firefox/ffAccessibility.ts index e757b05c28..ce057dba0f 100644 --- a/src/firefox/ffAccessibility.ts +++ b/src/firefox/ffAccessibility.ts @@ -202,11 +202,10 @@ class FFAXNode implements accessibility.AXNode { serialize(): types.SerializedAXNode { const node: {[x in keyof types.SerializedAXNode]: any} = { role: FFRoleToARIARole.get(this._role) || this._role, - name: this._name || '' + name: this._name || '', }; const userStringProperties: Array = [ 'name', - 'value', 'description', 'roledescription', 'valuetext', @@ -236,16 +235,6 @@ class FFAXNode implements accessibility.AXNode { continue; node[booleanProperty] = value; } - const tristateProperties: Array = [ - 'checked', - 'pressed', - ]; - for (const tristateProperty of tristateProperties) { - if (!(tristateProperty in this._payload)) - continue; - const value = this._payload[tristateProperty]; - node[tristateProperty] = value; - } const numericalProperties: Array = [ 'level' ]; @@ -266,6 +255,13 @@ class FFAXNode implements accessibility.AXNode { continue; node[tokenProperty] = value; } - return node; + + const axNode = node as types.SerializedAXNode; + axNode.valueString = this._payload.value; + if ('checked' in this._payload) + axNode.checked = this._payload.checked === true ? 'checked' : this._payload.checked === 'mixed' ? 'mixed' : 'unchecked'; + if ('pressed' in this._payload) + axNode.pressed = this._payload.pressed === true ? 'pressed' : 'released'; + return axNode; } } diff --git a/src/rpc/server/pageDispatcher.ts b/src/rpc/server/pageDispatcher.ts index cf0cc28d32..39e19b17f5 100644 --- a/src/rpc/server/pageDispatcher.ts +++ b/src/rpc/server/pageDispatcher.ts @@ -20,7 +20,7 @@ import { Frame } from '../../frames'; import { Request } from '../../network'; import { Page, Worker } from '../../page'; import * as types from '../../types'; -import { BindingCallChannel, BindingCallInitializer, ElementHandleChannel, PageChannel, PageInitializer, ResponseChannel, WorkerInitializer, WorkerChannel, JSHandleChannel, Binary, SerializedArgument, PagePdfParams, SerializedError, PageAccessibilitySnapshotResult, SerializedValue, PageEmulateMediaParams, AXNode } from '../channels'; +import { BindingCallChannel, BindingCallInitializer, ElementHandleChannel, PageChannel, PageInitializer, ResponseChannel, WorkerInitializer, WorkerChannel, JSHandleChannel, Binary, SerializedArgument, PagePdfParams, SerializedError, PageAccessibilitySnapshotResult, SerializedValue, PageEmulateMediaParams } from '../channels'; import { Dispatcher, DispatcherScope, lookupDispatcher, lookupNullableDispatcher } from './dispatcher'; import { parseError, serializeError } from '../serializers'; import { ConsoleMessageDispatcher } from './consoleMessageDispatcher'; @@ -184,7 +184,7 @@ export class PageDispatcher extends Dispatcher implements interestingOnly: params.interestingOnly, root: params.root ? (params.root as ElementHandleDispatcher)._elementHandle : undefined }); - return { rootAXNode: rootAXNode ? axNodeToProtocol(rootAXNode) : undefined }; + return { rootAXNode: rootAXNode || undefined }; } async pdf(params: PagePdfParams): Promise<{ pdf: Binary }> { @@ -274,16 +274,3 @@ export class BindingCallDispatcher extends Dispatcher<{}, BindingCallInitializer this._reject!(parseError(params.error)); } } - -function axNodeToProtocol(axNode: types.SerializedAXNode): AXNode { - const result: AXNode = { - ...axNode, - valueNumber: typeof axNode.value === 'number' ? axNode.value : undefined, - valueString: typeof axNode.value === 'string' ? axNode.value : undefined, - checked: axNode.checked === true ? 'checked' : axNode.checked === false ? 'unchecked' : axNode.checked, - pressed: axNode.pressed === true ? 'pressed' : axNode.pressed === false ? 'released' : axNode.pressed, - children: axNode.children ? axNode.children.map(axNodeToProtocol) : undefined, - }; - delete (result as any).value; - return result; -} diff --git a/src/types.ts b/src/types.ts index 6dbecc60d4..7804b05118 100644 --- a/src/types.ts +++ b/src/types.ts @@ -290,7 +290,8 @@ export type LaunchPersistentOptions = LaunchOptionsBase & BrowserContextOptions; export type SerializedAXNode = { role: string, name: string, - value?: string|number, + valueString?: string, + valueNumber?: number, description?: string, keyshortcuts?: string, @@ -307,8 +308,8 @@ export type SerializedAXNode = { required?: boolean, selected?: boolean, - checked?: boolean | 'mixed', - pressed?: boolean | 'mixed', + checked?: 'checked' | 'unchecked' | 'mixed', + pressed?: 'pressed' | 'released' | 'mixed', level?: number, valuemin?: number, diff --git a/src/webkit/wkAccessibility.ts b/src/webkit/wkAccessibility.ts index 2beeaf6170..320fb16832 100644 --- a/src/webkit/wkAccessibility.ts +++ b/src/webkit/wkAccessibility.ts @@ -182,8 +182,18 @@ class WKAXNode implements accessibility.AXNode { node.roledescription = roledescription; } - if ('value' in this._payload && this._payload.role !== 'text') - node.value = this._payload.value; + if ('value' in this._payload && this._payload.role !== 'text') { + if (typeof this._payload.value === 'string') + node.valueString = this._payload.value; + else if (typeof this._payload.value === 'number') + node.valueNumber = this._payload.value; + } + + if ('checked' in this._payload) + node.checked = this._payload.checked === 'true' ? 'checked' : this._payload.checked === 'false' ? 'unchecked' : 'mixed'; + + if ('pressed' in this._payload) + node.pressed = this._payload.pressed === 'true' ? 'pressed' : this._payload.pressed === 'false' ? 'released' : 'mixed'; const userStringProperties: Array = [ 'keyshortcuts', @@ -217,16 +227,6 @@ class WKAXNode implements accessibility.AXNode { (node as any)[booleanProperty] = value; } - const tristateProperties: ('checked'|'pressed')[] = [ - 'checked', - 'pressed', - ]; - for (const tristateProperty of tristateProperties) { - if (!(tristateProperty in this._payload)) - continue; - const value = this._payload[tristateProperty]; - node[tristateProperty] = value === 'mixed' ? 'mixed' : value === 'true' ? true : false; - } const numericalProperties: Array = [ 'level', 'valuemax',