(Created page with "''NOTE: This article applies to Window-Eyes 7.X.'' Accessing the IE DOM through Window-Eyes apps isn't trivial, but it's certainly doable, and can provide you with a fairly comp...")
Newer edit →
Revision as of 19:33, 27 September 2011
NOTE: This article applies to Window-Eyes 7.X.
Accessing the IE DOM through Window-Eyes apps isn't trivial, but it's certainly doable, and can provide you with a fairly comprehensive method for getting feedback about a web page, including when specific events occur.
The first steps is obtaining the Native Object Model from the visible Internet Explorer_Server window. This is the window that hosts the web page content. We'll create a simple routine that we can refer to anytime we're after the NOM (Native Object Model).
Function GetNOM(wObj)
Dim ieChildren, ieChild, NOM
' Begin Set GetNOM = Nothing Set ieChildren = wObj.Children.FilterByClassAndModule("Internet Explorer_Server", "MSHTML") For Each ieChild In ieChildren If ieChild.Visible Then Set NOM = ieChild.NativeObjectModel If Not NOM Is Nothing Then Set GetNOM = NOM End If Exit For End If Next End Function
Our function takes one parameter, and that's the window that we're interesting in getting the NOM from. If you have your app associated to Internet Explorer, it's safe to use the ActiveWindow object when calling your GetNOM function. Once you have obtained a valid NOM object, you can then retrieve the document property (IHTMLDocument), or connect to the NOM's events.
The document property can be thought of as the root of the document's tree hierarchy. You can use it, among many other things, to get the location/URL of the current document.
Dim NOM : Set NOM = GetNOM(ActiveWindow)
If Not NOM Is Nothing Then Set currentDocument = NOM.document If Not currentDocument Is Nothing Then If TypeName(currentDocument) = "HTMLDocument" Then Dim location : Set location = currentDocument.location If Not location Is Nothing Then MsgBox "The URL for this page is: " & location.href End If End If End If End If
You can also monitor DOM events to determine when things happen, such as when a page loads, or when an even occurs for a specific element. The following proof of concept example demonstrates how to get a DOM object and monitor focus events for input edit boxes. If a focus occurs for an edit box that has the ARIA "required" attribute, it will be spoken. There are some additional enhancements for a fwe other controls as well as anchors. Note that controls typically do not get physical focus while Browse Mode is enabled, so you'll want to make sure that you've turned off Browse Mode before tabbing through controls.
' Begin
Option Explicit
Dim NOM, DOMEvents, DOMDocumentEvents, DOMElementEvents
Set DOMElementEvents = CreateObject("Scripting.Dictionary")
ConnectEvent DesktopWindow, "OnChildActivate", "OnChildActivate"
Sub OnChildActivate(wObj) ClearElementEvents() If wObj.ModuleName = "IEFRAME" Then Set NOM = GetNOM(wObj) If Not NOM Is Nothing Then DOMEvents = ConnectObject(NOM, "DOM_") DOM_onload() End If End If End SUb
Function GetNOM(wObj) Dim ieChildren, ieChild, NOM
' Begin Set GetNOM = Nothing Set ieChildren = wObj.Children.FilterByClassAndModule("Internet Explorer_Server", "MSHTML") For Each ieChild In ieChildren If ieChild.Visible Then Set NOM = ieChild.NativeObjectModel If Not NOM Is Nothing Then Set GetNOM = NOM End If Exit For End If Next End Function
Sub DOM_onload() Dim document
If Not NOM Is Nothing Then Set document = NOM.document If Not document Is Nothing Then If DOMDocumentEvents <> 0 Then Disconnect DOMDocumentEvents DOMDocumentEvents = 0 End If DOMDocumentEvents = ConnectObjectWithParameter(document, "DOC_", document) DOC_onreadystatechange document End If End If End Sub
Sub DOC_onreadystatechange(document)
Dim readyState, controls, control, controlName
On Error Resume Next readyState = document.readyState If Err.Number <> 0 Then readyState = Err.Description End If On Error Goto 0 If readyState = "complete" Then ClearElementEvents()
Set controls = document.getElementsByTagName("input") If controls.length > 0 Then DOMElementEvents.RemoveAll For Each control In controls If Not DOMElementEvents.Exists(DOMElementEvents.Count + 1) Then DOMElementEvents.Add DOMElementEvents.Count + 1, ConnectObjectWithParameter(control, "IE_", control) End If Next End If End If End Sub
Sub ClearElementEvents() Dim keys
If DOMElementEvents.Count > 0 Then ' Disconnect any existing events keys = DOMElementEvents.Keys For k = 0 To UBound(keys) If DOMElementEvents(keys(k)) <> 0 Then Disconnect DOMElementEvents(keys(k)) DOMElementEvents.Remove keys(k) End If Next End If End Sub
Sub IE_onfocus(theControl) Dim title
Select Case TypeName(theControl) Case "HTMLAnchorElement" ' If the anchor has a title attribute, speak it. title = theControl.getAttribute("title") If Len(title) > 0 Then Speak title End If Case "HTMLInputElement" ' If the control has an ARIA required attribute, speak required If theControl.getAttribute("aria-required") Then Speak "required" End If ' If the control is a checkbox, radio button, or standard button, speak the ARIA pressed state If theControl.Type = "checkbox" Or theControl.Type = "radio" Or theControl.Type = "button" Then Speak theControl.getAttribute("aria-pressed") End If End Select End Sub
' End


