webKit.py
5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#virtualBuffers/webKit.py
#A part of NonVisual Desktop Access (NVDA)
#Copyright (C) 2011 NV Access Inc
#This file is covered by the GNU General Public License.
#See the file COPYING for more details.
import ctypes
from . import VirtualBuffer, VirtualBufferTextInfo, VBufRemote_nodeHandle_t
import controlTypes
import NVDAObjects.IAccessible
import winUser
import IAccessibleHandler
import oleacc
from logHandler import log
import textInfos
import NVDAHelper
class WebKit_TextInfo(VirtualBufferTextInfo):
def _normalizeControlField(self,attrs):
accRole=attrs['IAccessible::role']
role = level = None
if accRole.isdigit():
accRole = int(accRole)
else:
if "H1" <= accRole <= "H6":
role = controlTypes.ROLE_HEADING
level = int(accRole[1])
else:
accRole = accRole.lower()
if not role:
role = IAccessibleHandler.IAccessibleRolesToNVDARoles.get(accRole, controlTypes.ROLE_UNKNOWN)
states = set(IAccessibleHandler.IAccessibleStatesToNVDAStates[x] for x in [1 << y for y in xrange(32)] if int(attrs.get('IAccessible::state_%s' % x, 0)) and x in IAccessibleHandler.IAccessibleStatesToNVDAStates)
attrs["role"] = role
attrs["states"] = states
if level:
attrs["level"] = level
return super(WebKit_TextInfo, self)._normalizeControlField(attrs)
class WebKit(VirtualBuffer):
TextInfo = WebKit_TextInfo
def __init__(self,rootNVDAObject):
super(WebKit,self).__init__(rootNVDAObject,backendName="webKit")
def __contains__(self,obj):
return winUser.isDescendantWindow(self.rootNVDAObject.windowHandle, obj.windowHandle)
def _get_isAlive(self):
if self.isLoading:
return True
root=self.rootNVDAObject
if not root:
return False
if not winUser.isWindow(root.windowHandle) or root.role == controlTypes.ROLE_UNKNOWN:
return False
return True
def getNVDAObjectFromIdentifier(self, docHandle, ID):
node=VBufRemote_nodeHandle_t()
NVDAHelper.localLib.VBuf_getControlFieldNodeWithIdentifier(self.VBufHandle, docHandle, ID,ctypes.byref(node))
if not node:
return None
lresult = NVDAHelper.localLib.VBuf_getNativeHandleForNode(self.VBufHandle, node)
if not lresult:
return None
return NVDAObjects.IAccessible.IAccessible(
IAccessibleObject=oleacc.ObjectFromLresult(lresult, 0, oleacc.IAccessible),
IAccessibleChildID=0, windowHandle=self.rootDocHandle)
def getIdentifierFromNVDAObject(self,obj):
if obj == self.rootNVDAObject:
return obj.windowHandle, 0
if not self.isReady or not obj.event_childID:
# We can only retrieve the node for objects obtained from events.
raise LookupError
node=VBufRemote_nodeHandle_t()
NVDAHelper.localLib.VBuf_getNodeForNativeHandle(self.VBufHandle, obj.event_childID,ctypes.byref(node))
docHandle=ctypes.c_int()
ID=ctypes.c_int()
NVDAHelper.localLib.VBuf_getIdentifierFromControlFieldNode(self.VBufHandle, node, ctypes.byref(docHandle), ctypes.byref(ID))
return docHandle.value, ID.value
def _searchableAttribsForNodeType(self,nodeType):
if nodeType=="formField":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_PUSHBUTTON,oleacc.ROLE_SYSTEM_RADIOBUTTON,oleacc.ROLE_SYSTEM_CHECKBUTTON,oleacc.ROLE_SYSTEM_COMBOBOX,oleacc.ROLE_SYSTEM_LIST,oleacc.ROLE_SYSTEM_TEXT],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_FOCUSABLE:[1]}
elif nodeType=="list":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_LIST]}
elif nodeType=="listItem":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_LISTITEM]}
elif nodeType=="button":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_PUSHBUTTON]}
elif nodeType=="edit":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TEXT],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_FOCUSABLE:[1]}
elif nodeType=="radioButton":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_RADIOBUTTON]}
elif nodeType=="comboBox":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_COMBOBOX]}
elif nodeType=="checkBox":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_CHECKBUTTON]}
elif nodeType=="graphic":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_GRAPHIC]}
elif nodeType=="focusable":
attrs={"IAccessible::state_%s"%oleacc.STATE_SYSTEM_FOCUSABLE:[1]}
elif nodeType.startswith("heading") and nodeType[7:].isdigit():
attrs={"IAccessible::role":["H"+nodeType[7:]]}
elif nodeType=="heading":
attrs={"IAccessible::role":["H1","H2","H3","H4","H5","H6"]}
elif nodeType=="link":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_LINK],"IAccessible::state_%d"%oleacc.STATE_SYSTEM_LINKED:[1]}
elif nodeType=="table":
attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TABLE]}
else:
return None
return attrs
def _activateNVDAObject(self, obj):
try:
obj.doAction()
return
except:
pass
log.debugWarning("could not programmatically activate field, trying mouse")
l=obj.location
if not l:
log.debugWarning("no location for field")
return
x=(l[0]+l[2]/2)
y=l[1]+(l[3]/2)
oldX,oldY=winUser.getCursorPos()
winUser.setCursorPos(x,y)
winUser.mouse_event(winUser.MOUSEEVENTF_LEFTDOWN,0,0,None,None)
winUser.mouse_event(winUser.MOUSEEVENTF_LEFTUP,0,0,None,None)
winUser.setCursorPos(oldX,oldY)
def _shouldSetFocusToObj(self,obj):
return obj.role!=controlTypes.ROLE_GROUPING and super(WebKit,self)._shouldSetFocusToObj(obj)