Skip to Main ContentWindow-Eyes  Braille Sense  CCTV  Voice Sense  SyncBraille  Support  Training
GW Micro - Unleashing the power of your mind's eye.
 

Working with the Internet Explorer Document Object Model - GWWiki

(Difference between revisions)
Jump to: navigation, search
Line 30: Line 30:
 
<code>
 
<code>
 
  Dim NOM : Set NOM = GetNOM(ActiveWindow)
 
  Dim NOM : Set NOM = GetNOM(ActiveWindow)
 
+
If Not NOM Is Nothing Then
+
If Not NOM Is Nothing Then
Set currentDocument = NOM.document
+
Set currentDocument = NOM.document
If Not currentDocument Is Nothing Then
+
If Not currentDocument Is Nothing Then
If TypeName(currentDocument) = "HTMLDocument" Then
+
If TypeName(currentDocument) = "HTMLDocument" Then
Dim location : Set location = currentDocument.location
+
Dim location : Set location = currentDocument.location
If Not location Is Nothing Then
+
If Not location Is Nothing Then
MsgBox "The URL for this page is: " & location.href
+
MsgBox "The URL for this page is: " & location.href
End If
+
End If
End If
+
End If
End If
+
End If
End If
+
End If
 
</code>
 
</code>
  
Line 49: Line 49:
 
  ' Begin
 
  ' Begin
 
  Option Explicit
 
  Option Explicit
 
+
 
  Dim NOM, DOMEvents, DOMDocumentEvents, DOMElementEvents
 
  Dim NOM, DOMEvents, DOMDocumentEvents, DOMElementEvents
 
  Set DOMElementEvents = CreateObject("Scripting.Dictionary")
 
  Set DOMElementEvents = CreateObject("Scripting.Dictionary")
 
+
 
  ConnectEvent DesktopWindow, "OnChildActivate", "OnChildActivate"
 
  ConnectEvent DesktopWindow, "OnChildActivate", "OnChildActivate"
 
+
 
  Sub OnChildActivate(wObj)
 
  Sub OnChildActivate(wObj)
ClearElementEvents()
+
ClearElementEvents()
If wObj.ModuleName = "IEFRAME" Then
+
If wObj.ModuleName = "IEFRAME" Then
Set NOM = GetNOM(wObj)
+
Set NOM = GetNOM(wObj)
If Not NOM Is Nothing Then
+
If Not NOM Is Nothing Then
DOMEvents = ConnectObject(NOM, "DOM_")
+
DOMEvents = ConnectObject(NOM, "DOM_")
DOM_onload()
+
DOM_onload()
End If
+
End If
End If
+
End If
End Sub
+
End Sub
 
+
 
  Function GetNOM(wObj)
 
  Function GetNOM(wObj)
Dim ieChildren, ieChild, NOM
+
Dim ieChildren, ieChild, NOM
+
' Begin
+
' Begin
Set GetNOM = Nothing
+
Set GetNOM = Nothing
Set ieChildren = wObj.Children.FilterByClassAndModule("Internet Explorer_Server", "MSHTML")
+
Set ieChildren = wObj.Children.FilterByClassAndModule("Internet Explorer_Server", "MSHTML")
For Each ieChild In ieChildren
+
For Each ieChild In ieChildren
If ieChild.Visible Then
+
If ieChild.Visible Then
Set NOM = ieChild.NativeObjectModel
+
Set NOM = ieChild.NativeObjectModel
If Not NOM Is Nothing Then
+
If Not NOM Is Nothing Then
Set GetNOM = NOM
+
Set GetNOM = NOM
End If
+
End If
Exit For
+
Exit For
End If
+
End If
Next
+
Next
End Function
+
End Function
 
+
Sub DOM_onload()
+
Sub DOM_onload()
Dim document
+
Dim document
+
If Not NOM Is Nothing Then
+
If Not NOM Is Nothing Then
Set document = NOM.document
+
Set document = NOM.document
If Not document Is Nothing Then
+
If Not document Is Nothing Then
If DOMDocumentEvents <> 0 Then
+
If DOMDocumentEvents <> 0 Then
Disconnect DOMDocumentEvents
+
Disconnect DOMDocumentEvents
DOMDocumentEvents = 0
+
DOMDocumentEvents = 0
End If
+
End If
DOMDocumentEvents = ConnectObjectWithParameter(document, "DOC_", document)
+
DOMDocumentEvents = ConnectObjectWithParameter(document, "DOC_", document)
DOC_onreadystatechange document
+
DOC_onreadystatechange document
End If
+
End If
End If
+
End If
End Sub
+
End Sub
 
+
 
+
Sub DOC_onreadystatechange(document)
Sub DOC_onreadystatechange(document)
+
Dim readyState, controls, control, controlName
Dim readyState, controls, control, controlName
+
+
On Error Resume Next
On Error Resume Next
+
readyState = document.readyState
readyState = document.readyState
+
If Err.Number <> 0 Then
If Err.Number <> 0 Then
+
readyState = Err.Description
readyState = Err.Description
+
End If
End If
+
On Error Goto 0
On Error Goto 0
+
If readyState = "complete" Then
If readyState = "complete" Then
+
ClearElementEvents()
ClearElementEvents()
+
 
+
Set controls = document.getElementsByTagName("input")
Set controls = document.getElementsByTagName("input")
+
If controls.length > 0 Then
If controls.length > 0 Then
+
DOMElementEvents.RemoveAll
DOMElementEvents.RemoveAll
+
For Each control In controls
For Each control In controls
+
If Not DOMElementEvents.Exists(DOMElementEvents.Count + 1) Then
If Not DOMElementEvents.Exists(DOMElementEvents.Count + 1) Then
+
DOMElementEvents.Add DOMElementEvents.Count + 1, ConnectObjectWithParameter(control, "IE_", control)
DOMElementEvents.Add DOMElementEvents.Count + 1, ConnectObjectWithParameter(control, "IE_", control)
+
End If
End If
+
Next
Next
+
End If
End If
+
End If
End If
+
End Sub
End Sub
+
 
+
Sub ClearElementEvents()
Sub ClearElementEvents()
+
Dim keys
Dim keys
+
+
If DOMElementEvents.Count > 0 Then
If DOMElementEvents.Count > 0 Then
+
' Disconnect any existing events
' Disconnect any existing events
+
keys = DOMElementEvents.Keys
keys = DOMElementEvents.Keys
+
For k = 0 To UBound(keys)
For k = 0 To UBound(keys)
+
If DOMElementEvents(keys(k)) <> 0 Then
If DOMElementEvents(keys(k)) <> 0 Then
+
Disconnect DOMElementEvents(keys(k))
Disconnect DOMElementEvents(keys(k))
+
DOMElementEvents.Remove keys(k)
DOMElementEvents.Remove keys(k)
+
End If
End If
+
Next
Next
+
End If
End If
+
End Sub
End Sub
+
 
+
Sub IE_onfocus(theControl)
Sub IE_onfocus(theControl)
+
Dim title
Dim title
+
+
Select Case TypeName(theControl)
Select Case TypeName(theControl)
+
Case "HTMLAnchorElement"
Case "HTMLAnchorElement"
+
' If the anchor has a title attribute, speak it.
' If the anchor has a title attribute, speak it.
+
title = theControl.getAttribute("title")
title = theControl.getAttribute("title")
+
If Len(title) > 0 Then
If Len(title) > 0 Then
+
Speak title
Speak title
+
End If
End If
+
Case "HTMLInputElement"
Case "HTMLInputElement"
+
' If the control has an ARIA required attribute, speak required
' If the control has an ARIA required attribute, speak required
+
If theControl.getAttribute("aria-required") Then
If theControl.getAttribute("aria-required") Then
+
Speak "required"
Speak "required"
+
End If
End If
+
' If the control is a checkbox, radio button, or standard button, speak the ARIA pressed state
' 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
If theControl.Type = "checkbox" Or theControl.Type = "radio" Or theControl.Type = "button" Then
+
Speak theControl.getAttribute("aria-pressed")
Speak theControl.getAttribute("aria-pressed")
+
End If
End If
+
End Select
End Select
+
End Sub
End Sub
+
' End
 
+
' End
+
 
</code>
 
</code>

Revision as of 19:38, 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


Text Size:
Decrease Text Size Increase Text Size

Personal tools

Powered by MediaWiki
Public Domain
© 2013 GW Micro, Inc. All Rights Reserved.
GW Micro, Inc.    725 Airport North Office Park    Fort Wayne, IN 46825
Ph: 260-489-3671 Fax: 260-489-2608    www.gwmicro.com    sales@gwmicro.com    support@gwmicro.com
Hours: M-F, 8a-5p, EDST