Approved.^ <(br a hre -"http:/Awwv.caot.org bobby"^ img ore) [/SPAN> <br><A HREF='http://www.cast.org/bobby' ><IMG 'Bobby logo', 'http://www.cast.org/bobby', ");" >
SRC]="http://www.cast.org/images/approved.gif ' alt="Bobby logo" ( /a br> [ 'Bobby logo');" >< a><br>
<SPAN id="WebReaderText7" *] This page has been tested for and found to be compliant with Section 508 using the UseableNet extension of [Macromedias Dreamweaver.');" page has been tested for and found to be compliant with Section 508 using the UseableNet extension
of] Macromedia's Dreamweaver. [</SPANxSPAN id="WebReaderText8" ' ');" >
</SPAN>
<SCRIPT LANGUAGE=JavaScript> function AttemptStoreSpan(whichItem, theText)
{ top.frames.SimTalkFrame.StoreSpan(whichItem, theText);
} function SendSpanlnformationfJ
{ try
{
AttemptStoreSpan(document.all.WebReaderTextO, " When Java Script is enabled, clicking on the Point-and-Read logo or putting the computers cursor over the logo (and keeping it there) will launch a new window with the webreeder, a talking browser that can read this web page aloud.");
AttemptStoreSpan(document.all.WebReaderTextl, " webreeder Instructions"); AttemptStoreSpan(document.all.WebReaderText2, "Once upon a time there were four little Rabbits, and their names were Flopsy, Mopsy, Cotton-tail, and Peter.");
AttemptStoreSpan(document.all.WebReaderText3, " They lived with their Mother in a sand-bank, underneath the root of a very big fir-tree."); AttemptStoreSpan(document.all.WebReaderText4, " Next page");
AttemptStoreSpan(document.all.WebReaderText5, " Back to Library Home Page");
AttemptStoreSpan(document.all.WebReaderText6, " This page is Bobby Approved."); AttemptStoreSpan(document.all.WebReaderText7, " This page has been tested for and found to be compliant with Section 508 using the UseableNet extension of Macromedias Dreamweaver.");
} catch(e) { setTimeout("SendSpanInformationO", 1000);
} }
SendSpanlnformationO; </SCRIPT>
<NOSCRIPT>The Point-and-Read Webreader requires JavaScript to operate.</NOSCRIPT>]
</body>
</html>
The text parsing required to identify sentences in the original source code for subsequent tagging by the span tags is preferably performed using Perl. This process is well known and thus is not described in detail herein. The Appendix provides source code associated with the navigation toolbar shown in Figs. 8-13.
E. CLIENT-SIDE EMBODIMENT
An alternative embodiment of the web reader is coded as a stand-alone client-based application, with all program code residing on the user's computer, as opposed to the online server-based embodiment previously described. In this client-based embodiment, the web page parsing, translation and conversion take place on the user's computer, rather than at the server computer.
The client-based embodiment functions in much the same way as the server-based embodiment, but is implemented differently at a different location in the network. This implementation is preferably programmed in C++, using Microsoft Foundation Classes ("MFC"), rather than a CGI -type program. The client-based Windows implementation uses a browser application based on previously installed components of Microsoft Internet Explorer.
Instead of showing standard MFC buttons on the user interface, this implementation uses a custom button class, one which allows each button to be highlighted as the cursor passes over it. Each button is oversized, and allows an icon representing its action to be shown on its face. Some of these buttons are set to automatically stay in an activated state (looking like a depressed button) until another action is taken, so as to lock the button's function to an "on" state. For example, a "Play" button activates a systematic reading of the web page document, and reading continues as long as the button remains activated. A set of such buttons is used to emulate the functionality of scroll bars as well. The document highlighting, reading and navigation is accomplished in a manner similar to the server-based embodiment following similar steps as the online server-based webreaders described above.
First, for the client-based embodiment, when the user's computer retrieves a document (either locally from the user's computer or from over the Internet or other network), the document is parsed into sentences using the "Markup Services" interface to the document. The
application calls functions that step through the document one sentence at a time, and inserts span tags to delimit the beginning and end of each sentence. The document object model is subsequently updated so that each sentence has its own node in the document's hierarchy. This does not change the appearance of the document on the screen, or the code of the original document.
The client-based application provides equivalent functionality to the onMouseOver event used in the previously described server-based embodiment. This client-based embodiment, however, does not use events of a scripting language such as Javascript or VBScript, but rather uses Microsoft Active Accessibility features. Every time the cursor moves, Microsoft Active Accessibility checks which visible accessible item (in this case, the individual sentence) the cursor is placed "over." If the cursor was not previously over the item, the item is selected and instructed to change its background color. When the cursor leaves the item's area (i.e., when the cursor is no longer "over" the item); the color is changed back, thus producing a highlighting effect similar to that previously described for the server-based embodiment. When an object such as a sentence or an image is highlighted, a new timer begins counting. If the timer reaches its end before the cursor leaves the object, then the object's visible text (or alternate text for an image) is read aloud by the text-to-speech engine. Otherwise, the timer is cancelled. If the item (or object) has a default action to be performed, when the text-to- speech engine reaches the end of the synthetically spoken text, another timer begins counting. If this timer reaches its end before the cursor leaves the object, then the object's default action is performed. Such default actions include navigating to a link, pushing or activating a button, etc. In this way, clickless point-and-read navigation is achieved and other clickless activation is accomplished.
The invention is not limited to computers operating a Windows platform or programmed using C++. Alternate embodiments accomplish the same steps using other programming languages (such Visual Basic), other programming tools, other browser components (e.g., Netscape Navigator) and other operating systems (e.g., Apple's Macintosh OS).
An alternate embodiment does not use Active Accessibility for highlighting objects on the document. Rather, after detecting a mouse movement, a pointer to the document is obtained. A function of the document translates the cursor's location into a pointer to an object within the document (the object that the cursor is over). This object is queried for its original background
color, and the background color is changed. Alternately, one of the object's ancestors or children is highlighted.
The present invention may be implemented with any combination of hardware and software. If implemented as a computer-implemented apparatus, the present invention is implemented using means for performing all of the steps and functions described above.
The present invention may be implemented with any combination of hardware and software. The present invention can be included in an article of manufacture (e.g., one or more computer program products) having, for instance, computer useable media. The media has embodied therein, for instance, computer readable program code means for providing and facilitating the mechanisms of the present invention. The article of manufacture can be included as part of a computer system or sold separately.
It will be appreciated by those skilled in the art that changes could be made to the embodiments described above without departing from the broad inventive concept thereof. It is understood, therefore, that this invention is not limited to the particular embodiments disclosed, but it is intended to cover modifications within the spirit and scope of the present invention.
APPENDIX
<HTML <HEAD><TITLE>Point-and-Read Controls< ΗTLE>
<object lD="SpeechPluginObj" CLASSID="CLSID:E4DFABBD-F5F6-11D3-8421-0080C6F79C42"
Width="0" Height="0">
<embed TYPE="application/x-SpeechPlugin" name="SpeechPluginObj" HIDDEN></embed> </object>
<SCRIPT LANGUAGE=JavaScript> var usePeedy = false; var useSFIplugin = false; var useHaptek = false; function IsSpeechPluginInstalled()
// Checks to see if SFI plugin is installed
{ if (navigator.appName = "Netscape')
{ if (navigator.plugins["SpeechPlugin"]) return (1); else return (0);
} else if (navigator.appName = "Microsoft Internet Explorer")
{ return CheckIEControl();
} } function SpeechStop(ID)
// This is a callback for when the speech plugin is done speaking.
// Accessible through Netscape, or called by VBSCRIPT : SpeechPluginObj SpeechStop(ID) // in Internet Explorer
{ try
{ if (delayedUrl != "" && delayedUrl != " ") eval("delayedUrlTimer = setTimeout('GoTo(\"" + delayedUrl + "\");',
2000);");
} catch(e){ }
} function Speak(whatToSay, channel)
// Takes a string of words to say, and an integer 1 or 2. 1 Means it's a text
// area, and 2 means it's a hyperlink.
{ if (useSFIplugin)
{ if (channel = 2) // Hyperlink
{ clearTimeout(delayedTextTimer2); delayedTextTimer2 = null; try{ SpeechPluginObj.Sρeak(whafToSay); } catch(e){ }
} else // Normal Text
{
clear Timeout(delayedTextTimer); delayedTextTimer = null; try{ SpeechPluginObj.Speak(whatToSay); } catch(e){ }
} function SpeechlnitO
{ useSFIplugin = IsSpeechPluginInstalled(); if (useSFIplugin)
SpeechPIuginObj.RegisterEvents(l);
} </SCRJPT> <NOSCRJPT>The Point-and-Read Webreader requires JavaScript to operate.</NOSCRIPT>
<SCRIPT LANGUAGE=VBSCRIPT> Function CheckIEControl()
Dim SpeechControl
On Error Resume Next
Set SpeechControl = CreateObject("IESP.SpeechControl.l")
CheckIEControl=IsObject(SpeechControl) End Function "for IE only Sub SpeechPluginObj SpeechStop(ID)
SpeechStop(lD) End Sub </SCRIPT> <NOSCRIPT>The Point-and-Read Webreader requires VBScript to operate.</NOSCRIPT>
<SCRIPT language=JavaScript> var browserName = navigator.appName; // Explorer or Netscape var browserVersion = navigator.app Version; // Which version var delayedTextTimer = null; // The mouseover delay timer var delayedTextTimer2 = null; // The timer until link text is read var speakReqText; // The request # of normal spoken text var speakReqLink; // The request # of a link's spoken text var originalUrl = ""; // Text URL var regExp begin = /originalUrl=/i; // Regular expression var regExp end = Λ&/; // Regular expression var regExp http = /http:W/i; // Regular expression var loc = 0; // temporary counter var delayedUrl = ""; // Will navigate here after delay var delayedUrlTarget = ""; // The target frame to navigate var delayedUrlTimer = null; // Delay till navigation after speech is done var scrollTimer = null; // Interval timer for scrolling var textCoIorScheme = 0; // 0 or 1, based on text color scheme var HnkColorScheme = 0; // 0 or 1 , based on link color scheme var textColorSwitchTimer = null; // Delay till text color switch activates var linkColorSwitchTimer = null; // Delay till link color switch activates var spanReferences = new Array; // One reference for each span tag var span Texts = new Array; // The text for each span tag
var lastSpanReference = null; // The last span tag used var lastSpanText = ""; // The last spoken span tag text var currentSpanReference = -1 ; // The current span tag number var numSpanReferences = 0; // How many span tags are there var aboutWindow = null; // Reference to the about window var delayedFormButton = null; // Reference to the button to be clicked var oldBorderWidth; var highlightBorder = true;
// Pre-load images used for buttons
// Each array is for one button, where
// [0] is the untouched "up" mode
// [1 ] is the mouseover yellow mode
// [2] is the yellow, depressed mode var BackButtonlmages = new Array('http://www.simtalk.com/webreader/BackButton_Up.gif ,
'http://www.simtalk.com/webreader BackButton_Over.gif, 'http://www.simtalk.com/webreader/BackButton_Down.gif); var ForwardButtonlmages = new Array('http://www.simtalk.com/webreader/ForwardButton_Up.gif,
'http://www.simtalk.com/webreader/ForwardButton_Over.gif,
'http://www.simtalk.com/webreader/ForwardButton_Down.gif); var StopButtonlmages = new Array('http://www.simtalk.com/webreader/StopButton_Up.gif ,
'http://www.simtalk.com webreader/StopButton_Over.gif, 'http://www.simtalk.com/webreader/StopButton_Down.gif); var RefreshButtonlmages = new Array('http://www. simtalk.com/webreader/RefreshButton_Up.gif,
'http://www.simtalk.com webreader/RefreshButton_Over.gif,
'http://www.simtalk.com/webreader/RefreshButton_Down.gif); var HomeButtonlmages = new Array('http://www.simtaIk.com/webreader/HomeButton_Up.gif ,
'http://www.simtalk.com/webreader/HomeButton_Over.gif, 'http://www.simtalk.com/webreader/HomeButton_Down.gif); var GoButtonlmages = new Array('http://www.simtalk.com/webreader/GoButton_Up.gif ,
'http://www.simtalk.com/webreader/GoButton_Over.gif, 'http://www.simtalk.com/webreader/GoButton_Down.gif); var DownButtonlmages = new Array('http://www.simtalk.com/webreader/DownButton_Up.gif ,
'http://www.simtalk.com/webreader/DownButton_Over.gif, 'http://www.simtalk.com/webreader/DownButton_Down.gif); var UpButtonlmages = new Array('http://www.simtalk.com/webreader UpButton_Up.gif ,
'http://www.simtalk.com/webreader/UpButton_Over.gif, 'http://www.simtalk.com/webreader/UpButton_Down.gif); var PageDownButtonlmages = new Array('http://www.simtalk.com/webreader/PageDownButton_Up.gif,
'http://www.simtalk.com/webreader/PageDownButton_Over.gif,
'http://www.simtalk.com/webreader/PageDownButton_Down.gif); var PageUpButtonlmages = new Array('http://www.simtalk.com/webreader/PageUpButton_Up.gif,
'http://www.simtalk.com/webreader/PageUpButton_Over.gif,
'http://www.simtalk.com/webreader/PageUpButton_Down.gif); var LeftButtonlmages = new Array('http://www.simtalk.com webreader/LeftButton_Up.gif ,
'http://www.simtalk.com webreader/LeftButton_Over.gif, 'http://www.simtalk.com/webreader/LeftButton_Down.gif);
var RightButtonlmages = new Array('http://www.simtalk.com/webreader/RightButton_Up.gif ,
'http://www.simtalk.com/webreader/RightButton_Over.gif, 'http://www.simtalk.com/webreader/RightButton_Down.gif); var SearchButtonlmages = new Array('http://www.simtalk.com/webreader/SearchButton_Up.gif ,
'http://www.simtalk.com/webreader/SearchButton_Over.gif, 'http://www.simtalk.com/webreader/SearchButton_Down.gif); var PrintButtonlmages = new Array('http://www.simtalk.com/webreader/PrintButton_Up.gif ,
'http://www.simtalk.com/webreader/PrintButton_Over.gif, 'http://www.simtalk.com/webreader/PrintButton_Down.gif); var FavoriteButtonlmages = new Array('http://www.simtalk.com/webreader/FavoriteButton_Up.gif,
'http://www.simtalk.com/webreader/FavoriteButton_Over.gif,
'http://www.simtalk.com/webreader/FavoriteButton_Down.gif); var PlayButtonlmages = new Array('http://www.simtalk.com/webreader/PlayButton_Up.gif ,
'http://www.simtalk.com/webreader/PlayButton_Over.gif, 'http://www.simtalk.com/webreader/PlayButton_Down.gif); var RepeatButtonlmages = new Array('http://www.simtalk.com/webreader/RepeatButton_Up.gif ,
'http://www.simtalk.com/webreader/RepeatButton_Over.gif,
'http://www.simtalk.com/webreader/RepeatButton_Down.gif); var AboutButtonlmages = new Array('http://www.simtalk.com/webreader/AboutButton_Up.gif ,
'http://www.simtalk.com/webreader/AboutButton_Over.gif, 'http://www.simtalk.com webreader/AboutButton_Down.gif); var BugButtonlmages = new Array('http://www.simtalk.com/webreader/BugButton_Up.gif ,
'http://www.simtalk.com/webreader/BugButton_Over.gif, 'http://www.simtalk.com/webreader/BugButton_Down.gif);
// Pre-load images for color switch buttons var ColorSwitchlmages = new Array('http://www.simtalk.corn/webreader/text-switch-l.jpg',
'http://www.simtalk.com webreader/text-switch-2.jpg', 'http://www.simtalk.com/webreader/link-switch- 1 jpg', 'http://www.simtalk.com/webreader/link-switch-2.jpg'); function StartO
// This is called by the BODY onLoad handler
// All initialization code goes here
{ if (originalUrl != "") document.forml .urlBox.value = originalUrl;
SpeechlnitQ;
// Make button images load faster CacheButtonlmagesO;
} function CacheButtonlmagesO
// This will cycle all buttons through their 3 modes, thereby caching
// the images and making button changes occur faster for the user.
{ for (i=2; i>-l; i— )
{
// First row buttons document.images.BackButton.src = BackButtonImages[i]; document.images.ForwardButton.src = ForwardButtonImages[i];
document t.images.StopButton.src = StopButtonImages[i]; d v.o^cuUmιιιe^n.tt.images.RefreshButton.src = RefreshButtonlmagesfi]; document.images.HomeButton.src = HomeButtonImages[i]; document.images.DownButton.src = DownButtonImages[i]; document.images.UpButton.src = UpButtonImages[i]; document.images.PlayButton.src = PlayButtonlmagesfi]; document.images.RepeatButton.src = RepeatButtonlmagesfi]; document.images.AboutButton.src = AboutButtonlmagesfi];
function Navigate()
// Takes the url in the box and navigates the lower frame there
// (Note: This is the Server version, so CGI parsing WILL be done.)
{
// Clear the sentence buffers lastSpanReference = null; lastSpanText = ""; currentSpanReference = -1 ; numSpanReferences = 0; window .top.frames.OriginalWebSite.location = "http://www.simtalk.com/cgi- bin/webreader.pl?originalFrame=yes&originalUrl=" + document.forml .urlBox.value;
} function GoTo(theUrl)
// Given a string, this function will first check to see if the string is one
// of several recognized commands (back, stop, etc) and if so, execute them.
// If it's not a recognized command, it's assumed to be a url, and will navigate there.
{ delayedTextTimer = null; delayedTextTimer2 = null; delayedUrl = ""; if (theUrl != "" && theUrl != " ")
{ command = theUrl.toLowerCase(); switch (command)
{ case "back": document.images['BackButton'].onmousedownO; parent.OriginalWebSite.history.back(); break; case "forward": document.images['ForwardButton'].onmousedown(); parent.frames.OriginalWebSite.history.forward(); break; case "refresh": document.images['RefreshButton'].onmousedownO; parent.frames.OriginalWebSite.location.reloadO; break; case "stop": document.images['StopButton'].onmousedownO;
TryToStopO; break; case "home": document.images['HomeButton'].onmousedownO;
GoHome(); break; case "go": document.images['GoButton'].onmousedownO;
Navigate(); break; case "scroll down": document.images['DownButton'].onmousedown();
StartScrollDownO; break; case "scroll up": document.images['UpButton'].onmousedownO;
StartScrollUpO; break; case "page down": document.images['PageDownButton'].onmousedown();
PageDown(); break; case "page up": document.images['PageUpButton'].onmousedown();
PageUpO; break; case "scroll left": document. images['LeftButton'].onmousedown();
StartScrollLeftO; break; case "scroll right": document.images['RightButton'].onmousedown();
StartScrollRightO; break; case "print": document.images['PrintButton'].onmousedownO;
Print(); break; case "search": document.images['SearchButton'].onmousedown();
Search(); break; case "play": document.images['PlayButton'].onmousedownO; break; case "repeat": document.images['RepeatButton'].onmousedown(); delayedUrl = "continue repeating";
PlayCurrentSentenceO; break; case "continue playing":
StopCurrentSentence(); currentSpanReference++; delayedUrl = "continue playing"; PlayCurrentSentenceO; break; case "continue repeating":
PlayCurrentSentenceO; delayedUrl = "continue repeating"; break;
case "about": document.images['AboutButton'].onmousedownO;
ShowAboutWindow(); break; case "favorite": document.images['FavoriteButton'].onmousedownO;
ShowFavoriteO; break; case "bug": document.images['BugButton'].onmousedown();
Bug(); break; case "close the about window": try{ about Window. close(); } catch(e){} break; case "form button": try{ delayedFormButton.clickO; } catch(e){} break; case "close this window": try{ window.top.close(); } catch(e){} break; default:
// Check for acceptable web page types if (theUrl.indexOfC' ailto:") > -1)
{ window.top.frames.OriginalWebSite. location, href = theUrl; return;
} loc = theUrl. indexOfC'http://"); if (loc > -1 || loc < 2)
{ theUrl = theUrl.substr(loc+7, theUrl. length); containsHttp = true;
} else
{ containsHttp = false;
} if(theUrl.indexOf(".htm") > -l || theUrl.indexOfC.html") > -l || theUrl.indexOf(" pl") > -l || theUrl.indexOf(".cgi") > -l || theUrl.indexOf(".asp") > -l || theUrl.indexOfC.txt") > -1 || theUrl.indexOf("/") < 0 || theUrl.substr(theUrl.length - 1, 1) = "/")
{ if (containsHttp) theUrl = "http://" + theUrl; if (delayedUrlTarget == "")
{ document.forml. urlBox.value = theUrl; Navigate();
} else
{ window.toρ.frames.priginalWebSite.frames[delayedUrlTarget].location = "http://www.simtalk.com/cgi-bin webreader.pl?originalFrame=yes&subFrame=yes&originalUrl=" + delayedUrl;
}
} else
{ if (containsHttp) theUrl = "http://" + theUrl; top.location.href = theUrl;
} function SetOriginalUrl(originalUrl)
// This is called by the lower frame as soon as it loads, passing a string
// url of the page's location. It will then update the url box and title.
{
/* Cancel any pending navigation or speech clearTimeout(delayedUrlTimer); clearTimeout(delayedTextTimer); clearTimeout(delayedTextTimer2); delayedUrl = ""; */
// Clear the sentence buffers lastSpanReference = null; lastSpanText = ""; currentSpanReference = -1; numSpanReferences = 0;
// Update URL Box loc = originalUrl.search(regExp_begin); originalUrl = originalUrl.substring(loc + 12, originalUrl.length); loc = originalUrl.search(regExp end); if (loθ -l) originalUrl = originalUrl.substring(0, loc); // Add "http://" if not present loc = originalUrl.search(regExp http); if(loc < 0) originalUrl = "http://" + originalUrl; document.forml. urlBox.value = originalUrl;
// Update document title window.top.document.title = "Point-and-Read: " + window.top.frames.OriginalWebSite.documen title; } function CursorOver(whichItem, theText)
// Called by the lower frame when the mouse moves over a text area, passing
// a reference to the area, and a string of the text in that area.
// It will highlight the text and start a timer to call the speech engine.
{ overSentence = whichltem;
b overSentence = true; Highlight(overSentence); clearTimeout(delayedTextTimer); if (delayedTextTimer2 = null) delayedTextTimer = setTimeout("Speak('" + theText + "', 1); SetCurrentSpan('" + theText + '");",
1000);
} function Cursorθut(whichltem)
// Called by the lower frame when the mouse moves away from a text area, passing // a reference to that area. This will un-highlight the area and cancel and pending // speech synthesis.
{ overSentence = null; b overSentence = false;
ResetColors(whichltem); clearTimeout(delayedTextTimer); } function CursorOverLink(whichItem, theText, theUrl, theTarget) // Called by the lower frame when the mouse moves over a link, passing // a reference to the link, a string of the text in that area, the link's // url, and the specified target. It will highlight the text and start a // timer to call the speech engine.
{ ■
HighlightLink(whichltem); delayedUrl = theUrl; delayedUrlTarget = theTarget; clearTimeout(delayedTextTimer); delayedTextTimer2 = setTimeout("Speak('" + theText + '", 2)", 1000); } function CursorOutLink(whichltem)
// Called by the lower frame when the mouse moves away from a link area, passing // a reference to that area. This will un-highlight the area and cancel and pending // speech synthesis.
{
ResetColors(whichltem); clearTimeout(delayedTextTimer); cIearTimeout(delayedTextTimer2); clearTimeout(delayedUrlTimer); delayedTextTimer2 = null; delayedUrl = ""; delayedUrlTarget = ""; } function CursorOverButton(whichButton, command) // Called by this web page when the mouse moves over a command button, // along with a reference to that button and the string command. The status // bar will reflect the command, and the button will be treated as a link
{ highlightBorder = false;
CursorOverLink(whichButton, command, command); window. status = command;
} function CursorOutButton(whichButton)
// Called by this web page when the mouse moves away from a command button.
// The status bar will be reset, and the button will be treated as a cancelled link.
{ highlightBorder = true; CursorOutLink(whichButton); window.status = ";
} function CursorOverFormButton(whichltem)
// Called by the lower frame when the mouse moves over a button
{
Highlight(whichltem); delayedUrl = "Form Button"; delayedFormButton = whichltem; delayedUrlTarget = ""; clear Timeout(delayedTextTimer); delayedTextTimer2 = setTimeout("Speak('" + whichltem.value + '", 2)", 1000); } function CursorOutFormButton(whichltem)
// Called by the lower frame when the mouse moves away from a button
{
ResetColors(whichltem); clearTimeout(delayedTexfTimer); clearTimeout(delayedTextTimer2); clearTimeout(delayedUrlTimer); delayedTextTimer2 = null; delayedUrl = ""; delayedUrlTarget = ""; delayedFormButton = null; } function Highlight(whichltem)
// Given a reference to a text area, this will check the current color
// scheme and highlight the area appropriately using style attributes.
{
// Highlight text if ((document. all||document.getElementByld))
{ try { if (textColorScheme = 0)
{ whichltem.style.backgroundColor = "yellow"; whichltem.style.color = "black";
} else
{ whichltem.style.backgroundColor = "OOOOFF"; whichltem.style.color = "white";
} catch(e){}
} function HighlightLink(whichltem)
// Given a reference to a hyperlink area, this will check the current color
// scheme and highlight the area appropriately using style attributes.
{
// Highlight text if((document.all||document.getElementById))
{ try { oldBorderWidth = whichltem.border; if (highlightBorder) whichltem.border = 2; if (linkColorScheme = 0)
{ whichltem.style.backgroundColor = "cyan"; whichltem.style.color = "black";
} else
{ whichltem.style.backgroundColor = "00FF00"; whichltem.style.color = "black";
}
} catch(e){}
} function ResetColors(whichltem)
// Given a reference to a text or link area, this will reset the colors
// in the style attributes.
{ try
{ whichltem.style.backgroundColor = ""; whichltem.style.color = ""; whichltem.border = oldBorderWidth;
} catch(e){}
} function TryToStopO
// Called by the StopButton, this "attempts" to stop the browser from navigation.
{
// window's stop method only works with Netscape 4+ if (browserName.indexOf("Netscape") > -1) window.stop();
} function ScrollDown()
// This contacts the lower frame and two of its subframes (if they exist),
// causing them to scroll down
if (window. scrollBy)
{ if (window .top.frames.OriginalWebSite.frames[0]) window.top.frames.OriginalWebSite.frames[0].scrollBy(0, 20); if(window.top.frames.OriginalWebSite.frames[l]) window.top.frames.OriginalWebSite.frames[l].scrollBy(0, 20); window.top.frames.OriginalWebSite.scrollBy(0, 20); }
} function ScrollUpO
// This contacts the lower frame and two of its subframes (if they exist),
// causing them to scroll up
{ if (window. scrollBy)
{ if (window.top.frames.OriginalWebSite.frames[0]) window.top.frames.OriginalWebSite.frames[0].scrollBy(0, -20); if (window .top.frames.Original WebSite.framesf 1 ]) window.top.frames.OriginalWebSite.frarnes[l].scrollBy(0, -20); window.top.frames.OriginalWebSite.scrollBy(0, -20); } } function StartScrollDownO
// Starts an interval, scrolling down one unit periodically
{ scrollTimer = setInterval("ScrollDown();", 250);
} function StopScrollDownO
// Cancels the down-scrolling action
{ clearlnterval(scrollTimer);
} function StartScrollUpO
// Starts an interval, scrolling up one unit periodically
{ scrollTimer = setInterval("ScrollUpO;'\ 250);
} function StopScrollUpO
// Cancels the up-scrolling action
{ clearlnterval(scrollTimer);
} function ScrollLeft()
// This contacts the lower frame and two of its subframes (if they exist),
// causing them to scroll left
{ if (window .top.frames.OriginalWebSite.frames[0]) window.top.frames.Original WebSite.frames[0] .scrollBy(-20, 0); if (window .top.frames.OriginalWebSite.frames[l])
window.top.frames.OriginalWebSite.frames[l].scrollBy(-20, 0); window.top.frames.OriginalWebSite.scrollBy(-20, 0); } function ScrollRight()
// This contacts the lower frame and two of its subframes (if they exist),
// causing them to scroll right
{ if (window.scrollBy)
{ if(window.top.frames.OriginalWebSite.frames[0]) window.top.frames.OriginalWebSite.frames[0].scrollBy(20, 0); if (window.top.frames.Original WebSite.frames[ 1 ]) window.top.frames.OriginalWebSite.frames[l].scrollBy(20, 0); windo .top.frames.OriginalWebSite.scrollBy(20, 0); } } function StartScrollLeftO
// Starts an interval, scrolling left one unit periodically
{ scrollTimer = setInterval("ScrollLeftO;", 250);
} function StopScrollLeft()
// Cancels the left-scrolling action
{ clearlnterval(scrollTimer);
} function StartScrollRight()
// Starts an interval, scrolling right one unit periodically
{ scrollTimer = setInterval("ScrollRight();", 250); } function StopScroIlRight()
// Cancels the right-scrolling action
{ clearlnterval(scrollTimer);
} function PageDown()
// This contacts the lower frame and two of its subframes (if they exist),
// causing them to page down one screen full
{ if (window.scrollBy)
{ if (window.top.frames.OriginalWebSite.frames[0]) window.top.frames.OriginalWebSite.frames[0].scrollBy(0, window.innerHeight ? window.innerHeight : document.body.clientHeight); if (window.top.frames.OriginalWebSite.frames[ 1 ]) window .top.frames.OriginalWebSite.frames[l].scrollBy(0, window.innerHeight ? window.innerHeight : document.body.clientHeight); window.top.frames.OriginalWebSite.scrollBy(0, window.innerHeight ? window.innerHeight : document.body.clientHeight);
} function PageUp()
// This contacts the lower frame and two of its subframes (if they exist),
// causing them to page up one screen full
{ if (window.scrollBy)
{ if (window.top.frames.OriginalWebSite.frames[0]) window .top.frames.OriginalWebSite.frames[0].scrollBy(0, window.innerHeight ? -window.innerHeight : - document.body.clientHeight); if (window.top.frames.OriginalWebSite.frames[ 1 ]) window.top.frames.OriginalWebSite.frames[l].scrollBy(0, window.innerHeight ? -window.innerHeight : - document.body.clientHeight); window .top.frames.OriginalWebSite.scrollBy(0, window.innerHeight ? - window.innerHeight : - document.body.clientHeight); } } function GoHome()
// Navigates the lower frame to a pre-determined home page
{ document.form 1.urlBox.value- http://www.simtalk.com/library/PeterRabbit/prl .htm';
Navigate(); } function ShowSearch()
// Navigates the lower frame to a pre-determined search page
{ document.forml. urlBox.value='http://www.simtalk.com/webreader/webreaderdemo- tagged.html';
Navigate(); } function Print()
{
Speak("The ability to print is coming soon.", 2);
} function ShowAboutWindow()
{ if (usePeedy) voiceext = "peedy"; else if (useHaptek) voiceext = "haptek"; else voiceext = "sfi"; aboutWindow = window.open('http://www.simtalk.com/webreader/about_' + voiceext + '.htmr,'WebReader_AboutVdirectories=no,location=no,menubar=no,scrollbars=auto,status=no,toolbar=no,r esizable=yes,top=0,left='+((screen.width)-310)+',height=450,width=300') } function ShowFavoriteO
{
}
function Bug()
{
} function TextColorSwitch OverO
// Called when the mouse moves over the text color scheme switch.
{ clearTi eout(textColorSwitchTimer); textColorSwitchTimer = setTimeout("TextColorSwitch_ClickO;", 1200); } function TextColorSwitch_Out()
// Called when the mouse moves away from the text color scheme switch.
{ clearTimeout(textColorSwitchTimer);
} function TextColorSwitch_Click()
// Called when the user clicks on the text color scheme switch.
// It toggles the text color scheme.
{ if (textColorScheme == 0)
{ textColorScheme = 1 ; document.images['TextColorSwitch'].src = ColorSwitchlmagesfl];
} else
{ textColorScheme = 0; document.images['TextColorSwitch'].src = ColorSwitchlmagesFO];
} function LinkColorSwitch_Over()
// Called when the mouse moves over the link color scheme switch.
{ clearTimeout(linkColorSwitchTimer); linkColorSwitchTimer = setTimeout("LinkColorSwitch_Click();", 1200); } function LinkColorSwitch OutO
// Called when the mouse moves away from the link color scheme switch.
{ clearTimeout(linkColorSwitchTimer);
} function LinkColorSwitch ClickO
// Called when the user clicks the link color scheme switch.
// It toggles the link color scheme.
{ if (linkColorScheme = 0)
{ linkColorScheme = 1 ; document.images['LinkColorSwitch'].src = ColorSwitchImages[3]; }
else
{ linkColorScheme = 0; document.images['LinkColorSwitch'].src = ColorSwitchImages[2]; } } function PlaySentencesO
// Starts the continuous play mode with automatic advances.
{ if (numSpanReferences < 1) return; StopCurrentSentenceO; if (currentSpanReference > 0) currentSpanReference++; if (currentSpanReference >= numSpanReferences) currentSpanReference = 0; delayedUrl = "continue playing"; PlayCurrentSentenceO; } function PlayCurrentSentenceO
// Highlights and plays the current sentence.
{ if (currentSpanReference < 0 || currentSpanReference >= numSpanReferences)
{ delayedUrl = ""; if (currentSpanReference >= numSpanReferences) currentSpanReference = numSpanReferences - 1; return;
}
Highlight(spanReferences[currentSpanReference]); Speak(spanTexts[currentSpanReference], 1); } function StopCurrentSentenceO
// Resets the colors of the current sentence.
// If speaker should be stopped immediately, add that code here.
{ if (currentSpanReference > -1 && currentSpanReference < numSpanReferences) ResetColors(spanReferences[currentSpanReference]); } function StopPlayingSentences()
// Aborts the continuous play or continuous repeat mode.
{
StopCurrentSentenceO; delayedUrl = "";
} function StoreSpan(whichItem, theText)
// Called by the lower frame. This adds a reference to a span tag and
// the span tag's text to arrays for later access.
{ spanReferences[numSpanReferences] = whichltem; spanTexts[numSpanReferences] = theText;
nu SpanReferences++; currentSpanReference = 0; } function SetCurrentSpan(theText)
// Given a string of text, this will search the array of span texts. // If it finds a match, it will set the new current span reference // appropriately.
{ for (i=0; i<numSpanReferences; i++)
{ if (spanTexts[i] == theText)
{ currentSpanReference = i; break; } } }
// Bring the browser to the front of the user's desktop. setTimeout("top.focus();", 1000); top.focusO; //-->
</SCRIPT>
<NOSCRIPT>The Point-and-Read Webreader requires JavaScript to operate.</NOSCRIPT> </HEAD>
<BODY BGCOLOR=black Link="white" ALink="white" VLink="white"> <LINK REL='SHORTCUT ICON' HREF='http://www.simtalk.com/webreader/webreaderlogol6.ico'> <FORM NAME- form 1 ' ACTION='javascript:Navigate0;'>
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0" WIDTH="800"> <TR> <TD> <IMG name="BackButton" src="http://www.simtalk.com/webreader/BackButton_Up.gif 1 ]; CursorOverButton(this, 'Back');" ; CursorOutButton(this);" CursorOutButton(this); parent.OriginalWebSite.history.back();"> </TD> <TD> <IMG name="ForwardButton" src="http://www.simtalk.com webreader/ForwardButton_Up.gif CursorOverButton(this, 'Forward');" CursorOutButton(this);" 1 ]; CursorOutButton(this); parent.frames.OriginalWebSite.history.forward();"> </TD> <TD> <IMG name="StopButton" src="http://www.simtalk.com/webreader/StopButton_Up.gif' CursorOverButton(this, 'Stop');" CursorOutButton(this);" CursorOutButton(this); TryToStop();"> </TD> <TD> <IMG name="RefreshButton" src="http://www.simtalk.com/webreader/RefreshButton_Up.gif
1 ]; CursorOverButton(this, 'Refresh');" CursorOutButton(this);" CursorOutButton(this);" parent.frames.OriginalWebSite.location.reloadO^ </TD> <TD> <IMG name="HomeButton" src="http://www.simtalk.com/webreader/HomeButton_Up.gif 1 ]; CursorOverButton(this, 'Home');" CursorOutButton(this);" 1 ]; CursorOutButton(this); GoHome();"> </TD>
<TD WIDTH="64">
<CENTERxfont color=white>SFK/font></CENTER> </TD> <TD> <IMG name="PlayButton" src="http://www.simtalk.com/webreader/PlayButton_Up.gif 1 ]; CursorOverButton(this, 'Play');" CursorOutButton(this);" PlaySentences();" CursorOutButton(this); StopPlayingSentences();"> </TD> <TD> <IMG name="RepeatButton" src="http://www.simtalk.com/webreader/RepeatButton_Up.gif CursorOverButton(this, 'Repeat');" CursorOutButton(this); StopPlayingSentences();" 1 ]; CursorOutButton(this);" PlayCurrentSentenceO; "> </TD> <TD> <IMG name="DownButton" src="http://www. simtalk.com/webreader/DownButton_Up.gif CursorOverButton(this, 'Scroll Down');" CursorOutButton(this); StopScrollDown();" 1 ]; clearlnterval(scrollTimer); CursorOutButton(this); ScrollDown();"> </TD> <TD> <IMG name="UpButton" src="http://www.simtalk.com/webreader/UpButton_Up.gif CursorOverButton(this, 'Scroll Up');" ; CursorOutButton(this); StopScrollUpO;" clearlnterval(scrollTimer); CursorOutButton(this); ScrollUp();"> </TD> <TD> <IMG name="AboutButton" src="http://www.simtalk.com/webreader/AboutButton_Up.gif 1 ]; CursorOverButton(this, 'About');" CursorOutButton(this);" CursorOutButton(this); ShowAboutWindow();"> </TD>
<TD WIDTH="100">
<IMG NAME="TextColorSwitch" SRC="http://www.simtalk.com/webreader/text-switch-l jpg"
>
<IMG NAME="LinkColorSwitch" SRC="http://www.simtalk.com/webreader/link-switch-l jpg" </TD> </TR>
<INPUT TYPE=hidden NAME=urlBox SIZE=100>
</TABLE>
</FORM></BODY></HTML>
What IS clα d is