| Line 164: | Line 164: | ||
Once you have a document object, you can do all kinds of things with the page. For more information on interacting with the DOM, check out these pages: | Once you have a document object, you can do all kinds of things with the page. For more information on interacting with the DOM, check out these pages: | ||
| − | *[http://www.w3.org/DOM/ | + | *[http://www.w3.org/DOM/ w3.org - Document Object Model (DOM)] |
*[http://www.quirksmode.org/dom/intro.html quirksmode.org - W3C DOM -Introduction] | *[http://www.quirksmode.org/dom/intro.html quirksmode.org - W3C DOM -Introduction] | ||
*[https://secure.wikimedia.org/wikibooks/en/wiki/JavaScript/Introduction_to_the_Document_Object_Model_%28DOM%29 wikimedia.org - Introduction to the Document Object Model (DOM)] | *[https://secure.wikimedia.org/wikibooks/en/wiki/JavaScript/Introduction_to_the_Document_Object_Model_%28DOM%29 wikimedia.org - Introduction to the Document Object Model (DOM)] | ||
*[http://www.brainjar.com/dhtml/intro/ brainjar.com - Introduction to the Document Object Model] | *[http://www.brainjar.com/dhtml/intro/ brainjar.com - Introduction to the Document Object Model] | ||
Revision as of 12:32, 28 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
Once you have a document object, you can do all kinds of things with the page. For more information on interacting with the DOM, check out these pages:


