[orca] New test cases
- From: Joanmarie Diggs <joanied src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [orca] New test cases
- Date: Tue, 8 Jul 2014 18:50:50 +0000 (UTC)
commit 470e3ce346fd1d4381cb8a82463a183ee63ad0b8
Author: Joanmarie Diggs <jdiggs igalia com>
Date: Sat May 10 17:02:50 2014 -0400
New test cases
test/html/aria-alert.html | 132 ++
test/html/aria-button.html | 45 +
test/html/aria-checkbox.html | 147 ++
test/html/aria-progressbar.html | 129 ++
test/html/aria-role-list.html | 13 +
test/html/aria-slider.html | 281 +++
test/html/aria-spreadsheet.html | 1873 ++++++++++++++++++++
test/html/aria-tabpanel.html | 263 +++
test/html/aria-treegrid.html | 329 ++++
test/html/back.png | Bin 0 -> 125 bytes
test/html/{bugzilla_top.html => bugzilla-top.html} | 0
test/html/checked.gif | Bin 0 -> 863 bytes
test/html/left.png | Bin 0 -> 336 bytes
test/html/mixed.gif | Bin 0 -> 860 bytes
test/html/right.png | Bin 0 -> 336 bytes
test/html/slider.png | Bin 0 -> 301 bytes
test/html/unchecked.gif | Bin 0 -> 863 bytes
test/html/w3-checkbox-label-embedded-menu.html | 17 +
test/html/w3-checkbox-label-embedded-select.html | 17 +
test/html/w3-checkbox-label-embedded-slider.html | 12 +
.../w3-checkbox-label-embedded-spinbutton.html | 12 +
test/html/w3-checkbox-title.html | 9 +
test/html/w3-file-label-embedded-combobox.html | 21 +
test/html/w3-file-label-embedded-menu.html | 17 +
test/html/w3-file-label-embedded-select.html | 17 +
test/html/w3-file-label-embedded-slider.html | 12 +
test/html/w3-file-label-embedded-spinbutton.html | 12 +
test/html/w3-file-title.html | 9 +
test/html/w3-image-test.png | 2 +
test/html/w3-image-title.html | 9 +
test/html/w3-password-label-embedded-combobox.html | 21 +
test/html/w3-password-label-embedded-menu.html | 17 +
test/html/w3-password-label-embedded-select.html | 17 +
test/html/w3-password-label-embedded-slider.html | 12 +
.../w3-password-label-embedded-spinbutton.html | 12 +
test/html/w3-password-title.html | 9 +
test/html/w3-radio-label-embedded-combobox.html | 21 +
test/html/w3-radio-label-embedded-menu.html | 17 +
test/html/w3-radio-label-embedded-select.html | 17 +
test/html/w3-radio-label-embedded-slider.html | 12 +
test/html/w3-radio-label-embedded-spinbutton.html | 12 +
test/html/w3-radio-title.html | 9 +
test/html/w3-text-label-embedded-combobox.html | 21 +
test/html/w3-text-label-embedded-menu.html | 17 +
test/html/w3-text-label-embedded-select.html | 17 +
test/html/w3-text-label-embedded-slider.html | 12 +
test/html/w3-text-label-embedded-spinbutton.html | 12 +
test/html/w3-text-title.html | 9 +
48 files changed, 3642 insertions(+), 0 deletions(-)
---
diff --git a/test/html/aria-alert.html b/test/html/aria-alert.html
new file mode 100644
index 0000000..4e00e15
--- /dev/null
+++ b/test/html/aria-alert.html
@@ -0,0 +1,132 @@
+<html>
+<head>
+<style type="text/css">
+<!--
+.popup {
+ width: 20em;
+ height: 12em;
+ text-align: center;
+ border: 3px solid black;
+ background-color: white;
+ padding: 5%;
+ z-index: 100;
+ position: absolute;
+}
+.popup#alertDisp[aria-hidden="true"]
+ { display : none; }
+
+.popup#alertVis[aria-hidden="true"]
+ { visibility: hidden; }
+
+ .popup > div {
+ clear: both;
+ text-align: right;
+ margin-top: 5px;
+ }
+-->
+</style>
+
+<script type="text/javascript">
+<!--
+var gFocusItem = null;
+
+function doFocus() {
+ try {
+ if (gFocusItem != null) {
+ gFocusItem.focus();
+ gFocusItem=null;
+ }
+ } catch (error) {
+ alert("DEBUG: error in doFocus()");
+ }
+}
+
+var FOCUS_TEXT = "This div is created in the DOM as needed. Focus is set to it when it is displayed";
+var NOFOCUS_TEXT = "This div is created in the DOM as needed. Focus has NOT been set to it";
+var counter = 0;
+
+function createRemoveAlert(alertText, bGiveFocus)
+{
+ var popupDiv = document.getElementById("insertedAlert");
+ if (popupDiv) {
+ // Remove alert
+ var divParent = document.getElementById("alertParent");
+ divParent.removeChild(popupDiv);
+ return;
+ }
+
+ // Create alert
+ var popupDiv = document.createElement("div");
+ var dataNode = document.createTextNode(alertText);
+ popupDiv.appendChild(dataNode);
+ var close = document.createElement("a");
+ close.setAttribute("onclick", "createRemoveAlert();");
+ close.setAttribute("href", "#");
+ var closeText = document.createTextNode("close");
+ close.appendChild(closeText);
+ var closeDiv = document.createElement("div");
+ closeDiv.appendChild(close);
+ popupDiv.appendChild(closeDiv);
+
+ // try parenting to a div on the page rather than document.body
+ var divParent = document.getElementById("alertParent");
+ divParent.appendChild(popupDiv);
+ popupDiv.id = "insertedAlert";
+ popupDiv.setAttribute("role", "alert");
+ popupDiv.tabIndex = "-1";
+ popupDiv.className = "popup";
+
+ if (bGiveFocus) {
+ gFocusItem = popupDiv;
+ setTimeout("doFocus();", 0);
+ }
+ return false; // handled
+}
+
+function toggleAlert(alertId, bGiveFocus, contentId) {
+ var alertDiv = document.getElementById(alertId);
+ if (alertDiv.getAttribute("aria-hidden") == "true") {
+ alertDiv.removeAttribute("aria-hidden");
+ }
+ else {
+ alertDiv.setAttribute("aria-hidden", "true");
+ }
+ if (bGiveFocus == true) {
+ gFocusItem = (contentId)? document.getElementById(contentId) : alertDiv;
+ setTimeout("doFocus();",0);
+ }
+}
+-->
+</script>
+</head>
+<body>
+<div><button onclick="createRemoveAlert(FOCUS_TEXT, true);">Create and Focus</button></div>
+<div><button onclick="createRemoveAlert(NOFOCUS_TEXT, false);">Create - no Focus</button></div>
+<div><button onclick="toggleAlert('alertVis', true);">Show (via visibility style) and Focus</button></div>
+<div><button onclick="toggleAlert('alertVis');">Show (via visibility style) - no Focus</button></div>
+<div><button onclick="toggleAlert('alertDisp', true);">Show (via display style) and Focus</button></div>
+<div><button onclick="toggleAlert('alertDisp');">Show (via display style) - no Focus</button></div>
+<div><button onclick="toggleAlert('alertDisp', true, 'closeLink');">Show (via display style) and put focus
inside alert (on link)</button></div>
+<div role="alert" tabindex="-1" class="popup" aria-hidden="true" id="alertVis">
+ <span>This popup is created as a div in the HTML content, rather than being created in the DOM at
+ the time of use. The visibility style is changed from "hidden" to "visible"
+ to hide and show it.
+ </span>
+ <div style="text-align:right;margin-top:10px;">
+ <a href="javascript:toggleAlert('alertVis');">close</a>
+ </div>
+</div>
+<div role="alert" tabindex="-1" class="popup" aria-hidden="true" id="alertDisp">
+ <span>This popup is created as a div in the HTML content, rather than being created in the DOM at
+ the time of use. The display style is changed from "none" to "block"
+ to hide and show it.
+ </span>
+ <div style="text-align:right;margin-top:10px;">
+ <a id="closeLink" href="javascript:toggleAlert('alertDisp');">close</a>
+ </div>
+</div>
+<div id="alertParent">
+</div>
+<p>Some text after the alert to help with selection in order to view alert source</p>
+</body>
+</html>
diff --git a/test/html/aria-button.html b/test/html/aria-button.html
new file mode 100644
index 0000000..30a33cc
--- /dev/null
+++ b/test/html/aria-button.html
@@ -0,0 +1,45 @@
+<html>
+<head>
+<title>ARIA Button</title>
+<script type="text/javascript">
+<!--
+// Mouse and keyboard event handlers for controls
+function buttonEvent(event)
+{
+ if ((event.type == "click" && event.button == 0) ||
+ (event.type == "keydown" && (event.keyCode == 32 || event.keyCode ==13))) {
+ alert("Button pressed");
+ }
+};
+-->
+</script>
+<style type="text/css">
+ span[role="button"] { background-color: #eeeeee; margin: 1em; border: medium outset white;}
+
+ fieldset { max-width: 50%; }
+
+ fieldset > div { margin-top: 1em; }
+</style>
+</head>
+<body>
+ <fieldset aria-describedby="groupdesc1">
+ <legend>
+ Order tracking
+ </legend>
+ <div role="description" id="groupdesc1">
+ Order tracking has been enabled for all shipments outside of Texas. For information on orders to
Texas, please call 1-555-HELP-NOW for an automated recording.
+ </div>
+ <div>
+ <label for="tracknum">Tracking number</label> <input id="tracknum" type="text">
+ </div>
+ <div>
+ <span role="button" aria-checked="true" tabindex="0" aria-describedby="buttondesc1" onkeydown="return
buttonEvent(event);" onclick="return buttonEvent(event);">
+ Check Now
+ </span>
+ <span role="description" id="buttondesc1">
+ Check to see if your order has been shipped.
+ </span>
+ </div>
+ </fieldset>
+</body>
+</html>
diff --git a/test/html/aria-checkbox.html b/test/html/aria-checkbox.html
new file mode 100644
index 0000000..60c28a1
--- /dev/null
+++ b/test/html/aria-checkbox.html
@@ -0,0 +1,147 @@
+<html>
+<head>
+<title>ARIA Checkbox</title>
+
+<script type="text/javascript" >
+/*
+* @method public getTarget() - helper function to extract the element which fired the event from the event
object.
+* @param event - event object
+* @return - the appropriate target based on the varibles supported in the event object.
+*/
+function getTarget(event) {
+ var target = null;
+ if (event.target) {
+ target = event.target;
+ }
+ else if (event.srcElement) {
+ target = event.srcElement;
+ }
+ return target;
+}
+/******************* End of wrapper functions **********************/
+var CHECK = "checked.gif";
+var UNCHECK = "unchecked.gif";
+var MIXED = "mixed.gif";
+var ELEMENT_NODE = 1; // IE does not understand Node.ELEMENT_NODE nor nodeObj.ELEMENT_NODE
+// Mouse and keyboard event handlers for controls
+function checkBoxEvent(event)
+{
+ var bEventContinue = true; // Browser can still use event
+ try {
+ if ((event.type == "click" && event.button == 0) ||
+ (event.type == "keydown" && event.keyCode == 32)) {
+ // Toggle checkbox
+ var checkbox = getTarget(event);
+ var checkImg = null;
+ // event could be coming from img
+ if (checkbox.nodeType == ELEMENT_NODE && checkbox.tagName.toUpperCase() == "IMG") {
+ checkImg = checkbox;
+ checkbox = checkbox.parentNode;
+ }
+ else { //event coming from span
+ for (var i=0; i < checkbox.childNodes.length; i++) {
+ checkImg = checkbox.childNodes[i];
+ if (checkImg.nodeType == ELEMENT_NODE && checkImg.tagName.toUpperCase() == "IMG") {
+ break;
+ }
+ }
+ }
+ if (checkbox.getAttribute("aria-checked") == "true") {
+ checkbox.removeAttribute("aria-checked");
+ checkImg.src = UNCHECK;
+ }
+ else {
+ checkbox.setAttribute("aria-checked", "true");
+ checkImg.src = CHECK;
+ }
+ bEventContinue = false; // Do not continue propagating event
+ }
+ } catch (error) {
+ bEventContinue = true;
+ }
+ return bEventContinue;
+}
+
+function tristateCheckBoxEvent(event)
+{
+ var bEventContinue = true; // Browser can still use event
+ try {
+ if ((event.type == "click" && event.button == 0) ||
+ (event.type == "keydown" && event.keyCode == 32)) {
+ // Toggle checkbox
+ var checkbox = getTarget(event);
+ var checkImg = null;
+ // event could be coming from img
+ if (checkbox.nodeType == ELEMENT_NODE && checkbox.tagName.toUpperCase() == "IMG") {
+ checkImg = checkbox;
+ checkbox = checkbox.parentNode;
+ }
+ else { //event coming from span
+ for (var i=0; i < checkbox.childNodes.length; i++) {
+ checkImg = checkbox.childNodes[i];
+ if (checkImg.nodeType == ELEMENT_NODE && checkImg.tagName.toUpperCase() == "IMG") {
+ break;
+ }
+ }
+ }
+ if (checkbox.getAttribute("aria-checked") == "true") {
+ checkbox.removeAttribute("aria-checked");
+ checkImg.src = UNCHECK;
+ }
+ else if (checkbox.getAttribute("aria-checked") == "mixed") {
+ checkbox.setAttribute("aria-checked", "true");
+ checkImg.src = CHECK;
+ }
+ else {
+ checkbox.setAttribute("aria-checked", "mixed");
+ checkImg.src = MIXED;
+ }
+ bEventContinue = false; // Do not continue propagating event
+ }
+ } catch (error) {
+ bEventContinue = true;
+ }
+ return bEventContinue;
+};
+//]]>
+</script>
+</head>
+<body>
+ <p>Here's a checkbox that you can click on.</p>
+
+ <div>
+ <span role="checkbox" aria-checked="true" tabindex="0"
+ onkeydown="return checkBoxEvent(event);" onclick="return checkBoxEvent(event);" >
+ <img src="checked.gif" role="presentation" alt="" />
+ Include decorative fruit basket
+ </span>
+ </div>
+
+ <div>
+ <span role="checkbox" aria-checked="true" aria-invalid="true" tabindex="0"
+ onkeydown="return checkBoxEvent(event);" onclick="return checkBoxEvent(event);" >
+ <img src="checked.gif" role="presentation" alt="" />
+ Invalid checkbox
+ </span>
+ </div>
+
+ <div>
+ <span role="checkbox" aria-checked="true" aria-required="true" tabindex="0"
+ onkeydown="return checkBoxEvent(event);" onclick="return checkBoxEvent(event);" >
+ <img src="checked.gif" role="presentation" alt="" />
+ Required checkbox
+ </span>
+ </div>
+
+ <div>
+ <span role="checkbox" aria-checked="true" aria-required="true" tabindex="0"
+ onkeydown="return tristateCheckBoxEvent(event);" onclick="return tristateCheckBoxEvent(event);" >
+ <img src="checked.gif" role="presentation" alt="" />
+ Tri-state checkbox
+ </span>
+ </div>
+ <p>
+ <a href="/web/20110104115538/http://www.google.com/";>Random Google link</a>
+ </p>
+</body>
+</html>
diff --git a/test/html/aria-progressbar.html b/test/html/aria-progressbar.html
new file mode 100644
index 0000000..e11c904
--- /dev/null
+++ b/test/html/aria-progressbar.html
@@ -0,0 +1,129 @@
+<html>
+<head>
+<title>ARIA Progress Bar</title>
+<style type="text/css">
+<!--
+span[role="progressbar"] { color: red; font-family: courier; font-size: .1em;}
+*[aria-hidden] { visibility: hidden; }
+div[role="group"] { border: 3px solid black; width: 50%; }
+-->
+</style>
+<script>
+<!--
+function displayProgress(progress)
+{
+ var valueNow = parseInt(progress.getAttribute("aria-valuenow"));
+ var valueMin = parseInt(progress.getAttribute("aria-valuemin"));
+ var valueMax = parseInt(progress.getAttribute("aria-valuemax"));
+
+ // I'm sure there's something better than using a loop, but I don't feel like looking it up right now
+ var progressText = "|";
+ var count = valueMin;
+ for (; count < valueNow; count += 2) {
+ progressText += "*";
+ }
+ for (; count < valueMax; count += 2) {
+ progressText += "-";
+ }
+ progressText += "|";
+ progress.firstChild.data = progressText;
+ return false;
+}
+
+var gProgressId = "progress1"; // for now just a global to store the progress id
+var gbUpdate = false;
+var gTimerId = null;
+
+function updateProgress()
+{
+ // will update the first time it is drawn but so what - this is a prototype !
+ var progress = document.getElementById(gProgressId);
+ var valueNow = parseInt(progress.getAttribute("aria-valuenow"));
+ var valueMin = parseInt(progress.getAttribute("aria-valuemin"));
+ var valueMax = parseInt(progress.getAttribute("aria-valuemax"));
+ valueNow += 5;
+ if (valueNow < valueMin) {
+ valueNow = valueMin;
+ }
+ if (valueNow > valueMax) {
+ valueNow = valueMax; //loop around
+ }
+
+ progress.setAttribute("aria-valuenow", valueNow);
+
+ displayProgress(progress);
+
+ if (valueNow == valueMax) {
+ stopProgress();
+ var schedule = document.getElementById("schedule");
+ schedule.removeAttribute("aria-hidden");
+ schedule.className += ""; // Force IE7 reflow
+
+ }
+}
+
+function startProgress()
+{
+ gbUpdate = true;
+ gTimerId = setInterval("updateProgress();", 400);
+ document.getElementById("disabled").removeAttribute("disabled");
+}
+
+function stopProgress()
+{
+ gbUpdate = false;
+ if ( gTimerId != null) {
+ clearInterval(gTimerId);
+ gTimerId = null;
+ }
+ document.getElementById("disabled").setAttribute("disabled", "true");
+}
+-->
+</script><style type="text/css"></style>
+</head>
+
+<body onload="displayProgress(document.getElementById(gProgressId));">
+ <p>Here is a progress bar that you can start and stop using the buttons below. Both the progress bar and
the schedule are within an assertive live region.</p>
+
+ <p style="margin-top:2em;">
+ <button onclick="startProgress();">Load schedule</button><span style="padding-left:5em;"> </span>
+ <button id="disabled" onclick="stopProgress();" disabled="true">Cancel</button>
+ </p>
+ <p></p>
+ <div role="group" aria-live="assertive" aria-labelledby="scheduleLabel">
+ <h1 id="scheduleLabel">My schedule</h1>
+ <p> Loading schedule ...
+ <span role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="50" id="progress1" title="My
progress">|-------------------------|</span>
+ <table id="schedule" aria-hidden="true" border="1" cellpadding="3" cellspacing="0">
+ <tbody><tr>
+ <td>Monday</td>
+ <td>Work</td>
+ </tr>
+ <tr>
+ <td>Tuesday</td>
+ <td>Work</td>
+ </tr>
+ <tr>
+ <td>Wednesday</td>
+ <td>Work</td>
+ </tr>
+ <tr>
+ <td>Thursday</td>
+ <td>Work</td>
+ </tr>
+ <tr>
+ <td>Friday</td>
+ <td>Work</td>
+ </tr>
+ <tr>
+ <td>Saturday</td>
+ <td>Play</td>
+ </tr>
+ <tr>
+ <td>Sunday</td>
+ <td>Play</td>
+ </tr>
+ </tbody></table>
+ </p></div>
+</body>
+</html>
diff --git a/test/html/aria-role-list.html b/test/html/aria-role-list.html
new file mode 100644
index 0000000..1643583
--- /dev/null
+++ b/test/html/aria-role-list.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+<title>List</title>
+</head>
+<body>
+<div role="list">
+<div role="listitem">dog</div>
+<div role="listitem">cat</div>
+<div role="listitem">sparrow</div>
+<div role="listitem">wolf!</div>
+</div>
+</body>
+</html>
diff --git a/test/html/aria-slider.html b/test/html/aria-slider.html
new file mode 100644
index 0000000..e4bce8f
--- /dev/null
+++ b/test/html/aria-slider.html
@@ -0,0 +1,281 @@
+<html>
+<head>
+<title>Graphical ARIA Slider</title>
+<script type="text/javascript">
+/* ****** Variables to be set ****** */
+var sliderSize = 300; //Width of slider in pixels
+var moveValue = 10; //Value to change the slider on any action.
+
+function displaySlider(slider)
+{
+ var valueNow = parseInt(slider.getAttribute("aria-valuenow"));
+ var valueMin = parseInt(slider.getAttribute("aria-valuemin"));
+ var valueMax = parseInt(slider.getAttribute("aria-valuemax"));
+
+ var barWidth = slider.firstChild.scrollWidth;
+ var grade = sliderSize/valueMax;
+
+ //Set the left padding.
+ var leftPad = valueNow*grade-barWidth/2;
+ // if it is less then the min width.
+ if(leftPad < valueMin*grade){
+ leftPad = valueMin*grade;
+ }
+ // if it is greater than the max width
+ if(leftPad > valueMax*grade-barWidth){
+ leftPad = valueMax*grade-barWidth;
+ }
+ //The deferance between max and the current value, were going to use it like the valueMin was
+ var valueDown = valueMax-valueNow;
+ //Set the right padding
+ var rightPad = valueDown*grade-barWidth/2;
+ //If it is less than zero
+ if(rightPad < 0){
+ rightPad = 0;
+ }
+ //If it is too big
+ if(rightPad > valueMax*grade-barWidth-valueMin*grade){
+ rightPad = valueMax*grade-barWidth-valueMin*grade;
+ }
+
+ //Remove cases where *.5 is involved, this can cause the width to change by 1px if we don't fix it
+ if(rightPad >= leftPad){
+ var rightNew = Math.round(rightPad);
+ if(rightNew != rightPad){
+ rightPad = rightNew;
+ leftPad = leftPad-0.5;
+ }
+ }
+ if(leftPad >= rightPad){
+ var leftNew = Math.round(leftPad);
+ if(leftNew != leftPad){
+ leftPad = leftNew;
+ rightPad = rightPad-0.5;
+ }
+ }
+
+ //set the padding
+ slider.style.paddingRight = rightPad+'px';
+ slider.style.paddingLeft = leftPad+'px';
+
+ return false;
+}
+
+function handleSliderKey(slider, event)
+{
+ var valueNow = parseInt(slider.getAttribute("aria-valuenow"));
+ var valueMin = parseInt(slider.getAttribute("aria-valuemin"));
+ var valueMax = parseInt(slider.getAttribute("aria-valuemax"));
+
+ // Find the key press and respond to it
+ var delta = 0;
+ var delta = 0;
+ var kLeft = 37;
+ var kRight = 39;
+ var kHome = 36;
+ var kEnd = 35;
+ if (event.keyCode == kLeft) {
+ delta = -moveValue/2;
+ }
+ else if (event.keyCode == kRight) {
+ delta = moveValue/2;
+ }
+ else if (event.keyCode == kHome) {
+ delta = -( valueNow - valueMin );
+ }
+ else if (event.keyCode == kEnd) {
+ delta = valueMax - valueNow
+ }
+ else {
+ return true;
+ }
+
+ // Stop the values going over the max and min
+ valueNow += delta;
+ if (valueNow < valueMin) {
+ valueNow = valueMin;
+ }
+ if (valueNow > valueMax) {
+ valueNow = valueMax;
+ }
+
+ // Set the value and move the slider
+ slider.setAttribute("aria-valuenow", valueNow);
+ slider.setAttribute("aria-valuetext", "$" + valueNow + ".00" );
+ displaySlider(slider);
+
+ return false;
+}
+
+function sliderButton(event, where, id)
+{
+ var slider = document.getElementById(id);
+
+ var valueNow = parseInt(slider.getAttribute("aria-valuenow"));
+ var valueMin = parseInt(slider.getAttribute("aria-valuemin"));
+ var valueMax = parseInt(slider.getAttribute("aria-valuemax"));
+
+ if (where == 'after') {
+ var value = -moveValue;
+ } else {
+ var value = moveValue;
+ }
+
+ // Enter was pressed or mouse clicked on the button
+ if (event.keyCode == 13 || event.button == 0){
+ // Calculate new value
+ var valueNow = valueNow + value;
+
+ // Stop the values going over the max and min
+ if (valueNow < valueMin) {
+ valueNow = valueMin;
+ } else if(valueNow > valueMax) {
+ valueNow = valueMax;
+ }
+
+ // Set the value and move the slider
+ slider.setAttribute("aria-valuenow", valueNow);
+ slider.setAttribute("aria-valuetext", "$" + valueNow + ".00" );
+ displaySlider(slider);
+ }
+}
+
+function barMouseDown(event, bar)
+{
+ if (event.preventDefault) {
+ event.preventDefault();
+ }
+
+ bar.id = 'active';
+ try {
+ document.addEventListener('mousemove',mouseMove, true);
+ document.addEventListener('mouseup',barMouseUp, true);
+ } catch(ex) { // IE
+ document.attachEvent('onmousemove',mouseMove,true);
+ document.attachEvent('onmouseup',barMouseUp,true);
+ }
+
+ return false
+}
+
+function barMouseUp()
+{
+ var bar = document.getElementById('active');
+ bar.removeAttribute('id');
+
+ try {
+ document.removeEventListener('mousemove', mouseMove, true);
+ document.removeEventListener('mouseup', barMouseUp, true);
+ }
+ catch (ex) { // IE
+ document.detachEvent('onmousemove', mouseMove, true);
+ document.detachEvent('onmouseup', barMouseUp, true);
+ }
+}
+
+function mouseMove(event)
+{
+ //Get the slider we are moveing
+ var slider = document.getElementById('active').parentNode;
+ var valueNow = parseInt(slider.getAttribute("aria-valuenow"));
+ var valueMin = parseInt(slider.getAttribute("aria-valuemin"));
+ var valueMax = parseInt(slider.getAttribute("aria-valuemax"));
+
+ var grade = sliderSize/valueMax;
+
+ // Find what the new value should be and round it.
+ valueNow = event.clientX/grade-slider.offsetLeft/grade;
+ valueNow = Math.round(valueNow);
+
+ //Stop the values going over the max and min
+ if (valueNow < valueMin) {
+ valueNow = valueMin;
+ }
+ if (valueNow > valueMax) {
+ valueNow = valueMax;
+ }
+ //set the value and move the slider
+ slider.setAttribute("aria-valuenow", valueNow);
+ displaySlider(slider);
+}
+
+function sliderMouseDown(slider,event)
+{
+
+ var valueNow = parseInt(slider.getAttribute("aria-valuenow"));
+ var valueMin = parseInt(slider.getAttribute("aria-valuemin"));
+ var valueMax = parseInt(slider.getAttribute("aria-valuemax"));
+
+ var grade = sliderSize/valueMax;
+
+ // Find where was clicked, and were the bar is.
+ clickPos = event.clientX-slider.offsetLeft;
+ var barWidth = slider.firstChild.scrollWidth;
+ var barPos = slider.firstChild.offsetLeft-slider.offsetLeft;
+
+ // Change the value
+ if (clickPos > barPos && clickPos < barPos+barWidth) {
+ return true;
+ } else if(clickPos > barPos) {
+ var valueNow = valueNow+moveValue;
+ if(valueNow > clickPos/grade){
+ valueNow = clickPos/grade;
+ }
+ } else if(clickPos < barPos+barWidth) {
+ var valueNow = valueNow-moveValue;
+ if(valueNow < clickPos/grade){
+ valueNow = clickPos/grade;
+ }
+ }
+
+ // Set the value and move the slider
+ slider.setAttribute("aria-valuenow", valueNow);
+ displaySlider(slider);
+
+ if (event.preventDefault) {
+ event.preventDefault();
+ }
+
+ return false;
+}
+
+//--><!]]>
+</script>
+
+<style type="text/css">
+<!--
+span.right {
+ background:url('right.png') no-repeat;
+ width:17px;
+}
+span.left {
+ background:url('left.png') no-repeat;
+ width:17px;
+}
+#slider1 {
+ background:url('back.png') repeat-x;
+ height:17px;
+}
+.bar {
+ background:url('slider.png') no-repeat;
+ height:17px;
+ width:17px;
+}
+.slider span {
+ display:table-cell;
+}
+-->
+</style>
+<style type="text/css"></style></head>
+
+<body onload="displaySlider(document.getElementById('slider1'));">
+ <div class="slider">
+ <span>0</span>
+ <span role="button" title="Move slider left" class="left" onclick="sliderButton(event, 'after',
'slider1');" onkeypress="sliderButton(event, 'after', 'slider1');"></span>
+ <span title="My slider" tabindex="0" id="slider1" role="slider" aria-valuenow="10" aria-valuemin="0"
aria-valuemax="100" aria-valuetext="10%" onmousedown="sliderMouseDown(this,event);" onkeydown="return
handleSliderKey(this, event);" style="padding-right: 262px; padding-left: 21px;"><span class="bar"
onmousedown="barMouseDown(event,this)"></span>
+ </span>
+ <span title="Move slider right" role="button" class="right" onclick="sliderButton(event, 'before',
'slider1');" onkeypress="sliderButton(event, 'before', 'slider1');"></span>
+ <span>100</span>
+ </div>
+</body>
+</html>
diff --git a/test/html/aria-spreadsheet.html b/test/html/aria-spreadsheet.html
new file mode 100644
index 0000000..a36bdda
--- /dev/null
+++ b/test/html/aria-spreadsheet.html
@@ -0,0 +1,1873 @@
+<html>
+<head>
+<title>ARIA Spreadsheet and Menubar</title>
+<script type="text/javascript">
+<!--
+/* PLEASE NOTE THAT THIS IS PROTOTYPE CODE! It was created as a proof of concept and is not a well designed
or robust implementation! It is not meant to be a best practice example - please use accordinging! You have
been warned.
+*/
+// functions for changing style rules
+
+function changeStyleRule(oRule, styleName, styleValue) {
+ if (oRule.style && oRule.style.setProperty) {
+ oRule.style.setProperty(styleName, styleValue,"");
+ //alert(oRule.style.getPropertyValue(styleName));
+ }
+}
+
+
+// You must specify a "title" attribute in <style> tag or <link> tag for Mozilla.
+function pageGetStyleSheet(sID,doc) {
+ if(!doc)doc=document;
+ if(!sID)
+ return doc.styleSheets[0];
+
+ if (doc.all) {
+ return doc.styleSheets[sID];
+ } else {
+ for (var i = 0; i < doc.styleSheets.length; i++) {
+ var oSS = doc.styleSheets[i];
+ if (oSS.title == sID) return oSS;
+ }
+ }
+}
+
+function cssGetRules(oSS){
+ return (document.all ? oSS.rules : oSS.cssRules);
+}
+
+
+// SIMPLE function to find a particular rule selector
+function cssGetRule(rulesList, ruleIdent) {
+ var foundRule = null;
+ for (var i=0; i < rulesList.length; i++ ) {
+ var sText = rulesList[i].selectorText;
+ if (sText != "undefined" && sText != null) {
+ if (sText.indexOf(ruleIdent) > -1 ) {
+ foundRule = rulesList[i];
+ break;
+ }
+ }
+ }
+ return foundRule;
+}
+
+var TOP_SUFFIX = "top"; // the top menu item has an id that is menuID + TOP_SUFFIX
+var DROP_SUFFIX = "Items"; // the drop menu div has an id that is the menuID + DROP_SUFFIX
+var SUB_SUFFIX = "sub" // items that have sub menus have "sub" in the id
+var KEY_UP = 38;
+var KEY_DOWN = 40;
+var KEY_LEFT = 37;
+var KEY_RIGHT = 39;
+var KEY_ESCAPE = 27;
+var KEY_M=77;
+var KEY=F10 = 121;
+var KEY_SPACE = 32;
+var KEY_TAB = 9;
+
+
+var TEXT_NODE = 3;
+
+Menubar = function(menubarId) {
+ this.activeIdx = -1; // index of the active menu
+ this.dropOpen = false; // indicates if menu is open (items are visible)
+ this.itemIdx = -1; // indicates the index of the active item in an open menu
+ this.id = menubarId;
+ this.menus = new Array(); // array of menu Ids
+ this.menuItems = new Array(); // array of menu items - indexed by menu id
+ this.subMenus = new Array(); // array of sub menu items - indexed by parend menu id
+ this.activeSubId = null; // string with id of open sub menu; null if no sub menu open
+ this.activeSubIndex = -1; // index of active item in sub menu; -1 if no sub menu open
+
+}
+
+/* getters and setters for MenuState object
+*/
+
+Menubar.prototype.setActiveMenuIndex = function(index) {
+ this.activeIdx = index;
+}
+Menubar.prototype.getActiveMenuIndex = function() {
+ return this.activeIdx;
+}
+Menubar.prototype.setActiveOpen = function(isOpen) {
+ this.dropOpen = isOpen;
+}
+Menubar.prototype.isActiveOpen= function() {
+ return this.dropOpen;
+}
+Menubar.prototype.setActiveItemIndex = function(index) {
+ this.itemIdx = index;
+}
+Menubar.prototype.getActiveItemIndex = function() {
+ return this.itemIdx;
+}
+Menubar.prototype.updateAllIndex= function(active, drop, item) {
+ this.activeIdx = active;
+ this.dropOpen = drop;
+ this.itemIdx = item;
+}
+Menubar.prototype.getId = function() {
+ return this.id;
+}
+Menubar.prototype.getMenus = function() {
+ return this.menus; // return array of menu item ids
+}
+Menubar.prototype.getMenuItems = function(menuId) {
+ return this.menuItems[menuId];
+}
+/* Function to add a menu to the menu bar
+ ** Must be called in menu order!!
+ ** menuId - id of this menu item
+ ** items - array of ids for the menu items in this menu
+ ** returns number of menu items (lenght of menu array)
+ */
+Menubar.prototype.addMenu = function(menuId,items) {
+ this.menus[this.menus.length] = menuId;
+ this.menuItems[menuId] = items;
+
+}
+Menubar.prototype.addSubMenu = function(menuId, items) {
+ this.subMenus[menuId] = items;
+
+}
+Menubar.prototype.getSubMenuItems = function(itemId) {
+
+ return this.subMenus[itemId];
+}
+Menubar.prototype.setActiveSubOpen = function(menuId) {
+ this.activeSubId = menuId;
+}
+Menubar.prototype.getActiveSubOpen = function() {
+ return this.activeSubId;
+}
+Menubar.prototype.setActiveSubIndex= function(index) {
+ this.activeSubIndex = index;
+}
+Menubar.prototype.getActiveSubIndex = function() {
+ return this.activeSubIndex;
+}
+Menubar.prototype.hasSubMenu = function(itemObj) {
+ var bHasSub = false;
+ var itemId = itemObj.getAttribute("id");
+ // see if id contains "sub"
+ if (itemId.indexOf(SUB_SUFFIX) > -1) {
+ bHasSub = true;
+ }
+ return bHasSub;
+}
+
+Menubar.prototype.doMenu = function(event) {
+ //alert(event.ctrlKey + " : " + event.shiftKey + " : " + event.keyCode);
+ if (event.ctrlKey && event.altKey && event.keyCode == KEY_M) {
+ gFocusBeforeMenus = event.target;
+ //var theMenu = document.getElementById(this.getId());
+ // set focus to first menu (as long as menus are defined)
+ if (this.menus.length > 0) {
+
+ if (this.isActiveOpen() ) {
+ // close any open active items if press menu start key again
+ var activeIndex = this.getActiveMenuIndex();
+ var menu = document.getElementById((this.getMenus()[activeIndex] + DROP_SUFFIX));
+ menu.style.display="none";
+ this.updateAllIndex(-1,false,-1);
+
+ }
+ // set focus to the first menu
+ this.setActiveMenuIndex(0);
+ gFocusItem = document.getElementById((this.menus[0] + TOP_SUFFIX));
+ setTimeout("doFocus();",0);
+ } // end of if menus > 0
+ }
+}
+
+
+
+Menubar.prototype.doNavigation = function(event) {
+ var bEventContinue = true; // browser can still use event
+ var key = event.keyCode;
+ if ((key >=KEY_LEFT && key <= KEY_DOWN) || key == KEY_ESCAPE) {
+ var idx = this.getActiveMenuIndex();
+ if (idx < 0) {
+ idx = 0;
+ }
+ // if subIndex > -1 a submenu is open - up and down movement will occur in it
+ var subIndex = this.getActiveSubIndex();
+ var subMenuId = this.getActiveSubOpen();
+ var menus = this.getMenus();
+ var menuLen = menus.length;
+ var activeMenuId = menus[idx];
+ //var activeMenu = document.getElementById(activeMenuId);
+ var curDrop = document.getElementById(activeMenuId + DROP_SUFFIX);
+
+
+ if (key == KEY_LEFT || key == KEY_RIGHT) {
+
+ var nextIdx = idx;
+ if (key == KEY_LEFT) { // left
+ nextIdx = (idx + (menuLen-1)) % menuLen;
+
+ }
+ else { // right
+ nextIdx = ((idx + 1) % menuLen);
+ }
+ // if drop menu is displayed, close it and open the next one or move into submenu
+ var bShowNext = this.isActiveOpen();
+ if (bShowNext) {
+ // current drop is open, see if it has submenu
+ if (curDrop) {
+ if (subMenuId != null) {
+ // sub menu is open - close it
+ this.hideSubMenu();
+ if (key == KEY_LEFT) {
+ // find parentItem and set focus to it
+ gFocusItem = document.getElementById(subMenuId);
+ setTimeout("doFocus();",0);
+ return false;
+ }
+ // if right just close and move to next top level menu (which happens below)
+ } // end of submenu open
+ if (key == KEY_RIGHT && subMenuId == null) {
+ // if right arrow and sub menu is not open- get current item in the drop down and see if it has
a sub menu
+ var itemIdx = this.getActiveItemIndex();
+ var menuItems = this.getMenuItems(activeMenuId);
+ var curItemInDrop= document.getElementById(menuItems[itemIdx]);
+ var bHasSubMenu = this.hasSubMenu(curItemInDrop);
+ //alert(bHasSubMenu + " " + curItemInDrop.getAttribute("id"));
+ if (bHasSubMenu == true) {
+ return this.showSubMenu(event,curItemInDrop.getAttribute("id"));
+
+ }
+ }
+ // if haven't returned yet - then close the current drop
+ curDrop.style.display = "none"; // only one menudrop child per menu
+ this.setActiveItemIndex(0);
+
+ }
+
+ }
+ this.setActiveMenuIndex(nextIdx);
+ var nextMenuId = menus[nextIdx];
+ gFocusItem=document.getElementById(nextMenuId + TOP_SUFFIX);
+ if (bShowNext == true) {
+ var drop = document.getElementById(nextMenuId + DROP_SUFFIX);
+ if (drop) {
+ drop.style.display="block";
+ var menuItems = this.getMenuItems(nextMenuId);
+ gFocusItem=document.getElementById(menuItems[0]);
+ }
+ }
+
+ setTimeout("doFocus();",0);
+
+ }
+
+ if (key == KEY_UP || key == KEY_DOWN ) {
+ var itemIdx = this.getActiveItemIndex();
+ var bOpen = this.isActiveOpen();
+
+ if (curDrop) {
+ // first see if sub menu is open
+ if (subMenuId != null) {
+ // submenu is open - move within it
+ var subMenus = this.getSubMenuItems(subMenuId);
+ var subLen = subMenus.length;
+ var nextSubIndex =subIndex;
+ if (key == KEY_DOWN) {
+ nextSubIndex = (subIndex +1) % subLen;
+ }
+ else if (key == KEY_UP) {
+ nextSubIndex = (subIndex + (subLen - 1)) % subLen;
+ }
+ gFocusItem = document.getElementById(subMenus[nextSubIndex]);
+ this.setActiveSubIndex(nextSubIndex);
+ setTimeout("doFocus();",0);
+ return false;
+
+ } // end of if sub menus - back to regular processing
+
+ var menuItems = this.getMenuItems(activeMenuId);
+ var itemLen = menuItems.length;
+ var nextItemIdx;
+ if (!bOpen) { // open and set to the first item
+ this.showMenu(event, activeMenuId, true);
+ itemIdx = -1;
+ }
+ if (itemIdx == -1) {
+ nextItemIdx = 0;
+ }
+ else if (key == KEY_DOWN ){
+ nextItemIdx = (itemIdx +1) % itemLen;
+ }
+ else { //UP
+ nextItemIdx = (itemIdx + (itemLen-1)) % itemLen;
+ }
+
+ this.setActiveItemIndex(nextItemIdx);
+ gFocusItem=document.getElementById(menuItems[nextItemIdx]);
+ setTimeout("doFocus();",0);
+ } // end of id curDrop
+ } // end of id up/down
+ // need to prevent propagation of arrow keys
+ /* try {
+ ev.preventDefault();
+ }
+ catch (err) {
+ try {
+ ev.returnValue=false;
+ }
+ catch (errNext) {
+ ;
+ }
+ }*/
+ bEventContinue = false;
+
+ if (key == KEY_ESCAPE ) {
+ this.closeMenu(event);
+ bEventContinue = false;
+ if (gFocusBeforeMenus) {
+ gFocusItem = gFocusBeforeMenus;
+ setTimeout("doFocus();",0);
+ }
+ else {
+ document.focus();
+ }
+ } // end of if KEY_ESCAPE
+ } // end of if arrow or escape key
+ return bEventContinue;
+}
+Menubar.prototype.closeMenu = function(event) {
+// hide the menus
+ var isOpen = this.isActiveOpen();
+ var activeIndex = this.getActiveMenuIndex();
+ if (isOpen && activeIndex != -1) {
+ // find the index of the active menu and close
+ this.hideMenu(event);
+ }
+ else {
+ var menus = this.getMenus();
+ var activeMenuId = menus[activeIndex];
+ var curDrop = document.getElementById(activeMenuId + DROP_SUFFIX);
+ if (!isOpen && curDrop) {
+ // one of the top level menus is active but drop down is not open
+ gBlurItem = curDrop;
+ setTimeout("doBlur()",0);
+ }
+ }
+
+ this.updateAllIndex(-1,false,-1);
+ }
+
+Menubar.prototype.showMenu = function(event, menuId, bFocusFirst) {
+
+ // get the drop menu
+ var menu = document.getElementById((menuId + DROP_SUFFIX));
+ var displayState = "block";
+ var curIndex = this.findMenuIndex(menuId);
+ // see if any menu is open
+ var isOpen = this.isActiveOpen();
+ if (isOpen) {
+ // find the index of this menu item and see if it is different than the active one
+ var activeIndex = this.getActiveMenuIndex();
+
+ if (curIndex != activeIndex && activeIndex != -1 ) {
+ // close the currently open drop menu
+ this.hideMenu(event);
+ // show this one
+ displayState = "block";
+
+ }
+ else { // this is the current menu - hide it
+ displayState = "none";
+ }
+ } // end of if menu open
+ // else is not open - default value of displayState is block -so menu will be shown
+ // set the activeOpen value
+ var isOpen = (displayState == "block" ? true : false);
+ this.setActiveOpen(isOpen);
+ this.setActiveMenuIndex(curIndex);
+ // style="display:none" must be set on the drop elements to use the element.style.display syntax
+ // otherwise need to write cross browser routine to read the effective style (see DHTML book pg 878)
+ menu.style.display = displayState;
+ gFocusItem = menu; // may be over written is need to set focus on specific menu item
+ if (isOpen && bFocusFirst) {
+ // set focus to an item in the menu
+ if (this.getActiveItemIndex() == -1) {
+ this.setActiveItemIndex(0); // set to first item
+ }
+ var menuItems = this.getMenuItems(menuId);
+ gFocusItem=document.getElementById(menuItems[this.getActiveItemIndex()]);
+
+ }
+ setTimeout("doFocus();",0);
+
+}
+
+Menubar.prototype.showSubMenu = function(event, menuId) {
+// TODO fix to work with mouse - since only supporting keyboard right now - there will not be another drop
menu open
+
+// close any open submenus
+ this.hideSubMenu();
+
+ // get the drop menu
+ var menu = document.getElementById((menuId + DROP_SUFFIX));
+ var assocItem = document.getElementById(menuId);
+ //var container = assocItem.parentNode; // HACK - I know that containing div is parent of menuitem
should search for menuitem in parent chain
+ var displayState = "block";
+
+ this.setActiveSubOpen(menuId);
+ // will set focus to first item
+ this.setActiveSubIndex(0);
+ // position drop menu
+
+ var offTop= assocItem.offsetTop + "px";
+ var offLeft = assocItem.offsetLeft + assocItem.offsetWidth + "px";
+ with (menu.style) {
+ top=offTop;
+ left=offLeft;
+ display = displayState;
+ }
+
+ var subItems =this.getSubMenuItems(menuId);
+ var first = document.getElementById(subItems[0]);
+ gFocusItem = first;
+
+ setTimeout("doFocus();",0);
+ event.stopPropagation();
+ return false; // do not propagate event
+
+}
+Menubar.prototype.hideSubMenu = function() {
+ var openId = this.getActiveSubOpen();
+ if (openId != null) {
+ var openSub = document.getElementById(openId + DROP_SUFFIX);
+ openSub.style.display="none";
+ this.setActiveSubOpen(null);
+ this.setActiveSubIndex(-1);
+ }
+}
+
+Menubar.prototype.hideMenu = function(event) {
+ var isKey = false;
+ if (event.keyCode) {
+ isKey = true;
+ }
+ if ((isKey && event.keyCode == 13) || (isKey && event.keyCode == KEY_ESCAPE ) || !isKey) {
+ var isOpen = this.isActiveOpen();
+ var activeIndex = this.getActiveMenuIndex();
+ if (isOpen) {
+ var menu = document.getElementById((this.getMenus()[activeIndex] + DROP_SUFFIX));
+ // style="display:none" must be set on the drop elements to use the element.style.display syntax
+ // otherwise need to write cross browser routine to read the effective style (see DHTML book pg 878)
+ menu.style.display="none";
+ this.updateAllIndex(-1,false,-1);
+ this.hideSubMenu();
+ //event.cancelBubble = true; // this is not in the DOM but is supported by IE and Mozilla - could use
stopPropagation();
+ gBlurItem = menu;
+ setTimeout("doBlur();",0);
+
+ }
+
+
+ }
+
+}
+
+Menubar.prototype.findMenuIndex = function(menuId) {
+ var menus = this.getMenus();
+ var menuLen = menus.length;
+ var idx = -1;
+ for (var i=0; i < menuLen; i++ ) {
+ if (menus[i] == menuId) {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+}
+Menubar.prototype.clearMenu = function() {
+}
+
+Menubar.prototype.doAlert = function (event, theElem, alertStr) {
+// only called when is enter key or mouse click
+ var isKey = false;
+ if (event.keyCode) {
+ isKey = true;
+ }
+ if (theElem.getAttribute("aria-disabled") !="true") {
+ this.hideMenu(event);
+ gAlertString = alertStr;
+ setTimeout("delayedAlert(gAlertString);",0);
+
+ }
+ // always stop propagation of enter key or click
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ else {
+ try {
+ event.cancelBubble=true;
+ } catch (e) {
+ ;
+ }
+ }
+
+
+
+ return false; // do not propagate
+}
+
+
+Menubar.prototype.focusItem = function(event,menuIndex, itemIndex) {
+// called from onmouseover of each menu item
+ // TODO add error handling
+ this.setActiveItemIndex(itemIndex);
+ this.setActiveMenuIndex(menuIndex);
+ //this.setActiveOpen(true);
+ gFocusItem = event.target;
+ setTimeout("doFocus();",0);
+}
+
+Menubar.prototype.doActionTotal = function(event,tableId,key) {
+ this.hideMenu(event);
+ doTotals(tableId, key);
+ // always stop propagation of enter key or click
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ else {
+ try {
+ event.cancelBubble=true;
+ } catch (e) {
+ ;
+ }
+ }
+
+ return false;
+
+}
+Menubar.prototype.doActionColor = function(event,colorScheme) {
+ this.hideMenu(event);
+ doColor(colorScheme);
+ // always stop propagation of enter key or click
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ else {
+ try {
+ event.cancelBubble=true;
+ } catch (e) {
+ ;
+ }
+ }
+
+ return false;
+
+}
+function doAction(event, theElem) {
+
+ var isKey = false;
+ if (event.keyCode) {
+ isKey = true;
+ }
+ var bDoAction = false;
+ if ((isKey && event.keyCode == 13) || !isKey) {
+ if (theElem.getAttribute("aria-disabled") =="true") {
+ bDoAction = false;
+ }
+ else {
+ bDoAction = true;
+ }
+ }
+
+
+ return bDoAction;
+}
+
+
+
+
+var topMenu = new Menubar("menuBar");
+topMenu.addMenu("edit", new Array("cut","copy", "paste"));
+topMenu.addMenu("2", new Array("2.1sub", "2.2","2.3","2.4sub"));
+topMenu.addMenu("3", new Array("3.1", "3.2","3.3sub","3.4"));
+topMenu.addMenu("four", new Array("4.1", "4.2","4.3","4.4","4.5"));
+topMenu.addMenu("five", new Array("5.1", "5.2","5.3"));
+topMenu.addSubMenu("2.1sub", new Array("2.1.1", "2.1.2","2.1.3", "2.1.4", "2.1.5"));
+topMenu.addSubMenu("2.4sub", new Array("2.4.1", "2.4.2"));
+topMenu.addSubMenu("3.3sub", new Array("3.3.1", "3.3.2", "3.3.3"));
+
+
+
+// global vars for storing selection and focus information; indexed by the id of the parent table element
+var gCurrentRow = new Array();
+var gCurrentCol = new Array();
+var gCurrentSelected = new Array();
+var gCurrentCell = new Array();
+var gSelectedCells = new Array();
+var gSelecting = new Array();
+var gTabCount = new Array();
+
+gCurrentRow ["table2"] = -1; // 0 based row number
+gCurrentCol["table2"] = 0; // 0 based column number
+gCurrentSelected ["table2"]=null; // currently selected row object
+gCurrentCell["table2"] =null; // currently selected cell object
+gSelectedCells["table2"] = new Array(); // array of currently selected cell objects
+gSelecting["table2"] = false; // boolean indicating if currently in multi-select mode ( quicker than
checking for entries in gCurrentSelectedCells
+gTabCount["table2"] = 0; // need to know if tabbing into or out of control
+
+
+// global to store the item to be focused
+gFocusItem =null;
+// global to pass the item needing focus to doBlur() via a setTimeout()
+var gBlurItem= null;
+// global to store the alert string so can call alert() via setTimeout()
+gAlertString = "";
+
+function doFocus() {
+ try {
+ if (gFocusItem != null) {
+ gFocusItem.focus();
+ gFocusItem=null;
+ }
+ } catch (error) {
+ alert("DEBUG: error in doFocus()");
+ }
+}
+function doBlur() {
+ try {
+ if (gBlurItem != null) {
+ gBlurItem.blur();
+ gBlurItem=null;
+ }
+ } catch (error) {
+ alert("DEBUG: error in doBlur()");
+ }
+}
+
+function delayedAlert() {
+ alert(gAlertString);
+ gAlertString = "";
+}
+
+
+function setStyle(theObj, styleName, styleValue, priority) {
+ var bSuccess = false;
+
+ try {
+ if (theObj.style && theObj.style.setProperty) {
+ theObj.style.setProperty(styleName, styleValue,priority);
+ bSuccess = true;
+ }
+ } catch (ex) {
+ alert('exception caught setting style: ' + ex.message); // cannot do anything try the next method
+ }
+ if (!bSuccess) {
+ try {
+ theObj.style[styleName] = styleValue;
+ bSuccess = true;
+ } catch (exNext) {
+ alert('exception caught setting direct style: ' + exNext.message); // cannot do anything
+ }
+ }
+ return bSuccess;
+} // end of setStyle
+
+function findParentElem(evt, parentName) {
+ var srcElem = null;
+try {
+ if (evt.srcElement) {
+ srcElem = evt.srcElement;
+ }
+ else {
+ srcElem = evt.currentTarget;
+ }
+
+ if (srcElem != null ) {
+ // find the source table for the keyup event
+ var tagName = srcElem.tagName;
+ if (tagName != parentName) {
+ // search parent heirarchy
+ var parNode = srcElem.parentNode;
+ while (parNode != null) {
+ if (parNode.type == document.ELEMENT_TYPE) {
+ if (parNode.tagName.toLowerCase() == parentName) {
+ srcElem = parNode;
+ break;
+ }
+ }
+ parNode = parNode.parentNode;
+ }
+ }
+
+ }
+}
+catch (anyError) {
+ ; //srcElem = null;
+}
+ return srcElem;
+}
+
+function findParent (srcElem, parentName) {
+try {
+ if (srcElem != null ) {
+ // find the source table for the keyup event
+ var tagName = srcElem.tagName;
+ if (tagName != parentName) {
+ // search parent heirarchy
+ var parNode = srcElem.parentNode;
+ while (parNode != null) {
+ if (parNode.type == document.ELEMENT_TYPE) {
+ if (parNode.tagName.toLowerCase() == parentName) {
+ srcElem = parNode;
+ break;
+ }
+ }
+ parNode = parNode.parentNode;
+ }
+ }
+
+ }
+}
+catch (anyError) {
+ ; //srcElem = null;
+}
+ return srcElem;
+}
+
+
+function doTableKeys(e) {
+ var evt = (e != null) ? e : ((event) ? event : null); // Mozilla will include e parameter
+ var bDefaultHandler = true;
+ try {
+ var testCell = document.getElementById("testCell"); // could cache this test object for better performance
+ if (!testCell.focus) {
+ // test cell is the id of a table cell element with a tabindex="-1". See if we can set focus to it, if
+ // not, just return, we can not support arrow keys
+ //alert('no arrow key support');
+ return bDefaultHandler;
+ }
+
+ var srcElem = findParentElem(evt,"table");
+ //srcElem=document.getElementById(srcElem.getAttribute("id"));
+ var activeTableId = srcElem.getAttribute("id");
+ var rows = srcElem.rows;
+ var key = evt.keyCode;
+ var bCtrlKey = evt.ctrlKey;
+ var currentRow = gCurrentRow[activeTableId];
+ var currentCol = gCurrentCol[activeTableId];
+ var nextCell = null;
+
+ if ((key >= KEY_LEFT && key <= KEY_DOWN) && !evt.altKey) {
+ var nextRow = null;
+ var nextRowNum = 0;
+ var nextCol = null;
+ var nextColNum = 0;
+
+
+ if (gSelecting[activeTableId] == true && bCtrlKey == false) {
+ clearSelected(activeTableId);
+ }
+
+
+ // process arrows
+ if (key == KEY_DOWN ) { // down
+
+ nextRowNum = currentRow + 1;
+ if (rows.length > nextRowNum) {
+ var prevCell = null;
+ if (currentRow != -1) {
+ var prevRow = rows[currentRow];
+ prevCell = prevRow.cells[currentCol];
+ }
+ nextRow = rows[nextRowNum];
+ gCurrentRow[activeTableId]=nextRowNum;
+ nextCell = nextRow.cells[currentCol];
+ gCurrentCell[activeTableId] = nextCell;
+ processMovement(prevCell, nextCell, bCtrlKey, activeTableId);
+
+ gFocusItem = nextCell;
+ setTimeout("doFocus()", 0);
+
+ }
+ } // end of down
+ if (key == KEY_UP) { // up
+ nextRowNum = currentRow -1;
+ if (nextRowNum >=0 ) {
+ var prevCell = null;
+ if (currentRow != -1) {
+ var prevRow = rows[currentRow];
+ prevCell = prevRow.cells[currentCol];
+ }
+ nextRow = rows[nextRowNum];
+ gCurrentRow[activeTableId]=nextRowNum;
+ nextCell = nextRow.cells[currentCol];
+ gCurrentCell[activeTableId] = nextCell;
+ processMovement(prevCell, nextCell, bCtrlKey, activeTableId);
+ gFocusItem = nextCell;
+ setTimeout("doFocus()", 0);
+
+ }
+
+ } // end of up
+ if (key == KEY_LEFT ) { // left
+ nextColNum = currentCol -1;
+ var prevCell = null;
+ if (nextColNum >= 0 && currentRow >= 0) {
+ nextRow = rows[currentRow];
+ if (nextRow != null) {
+ prevCell = nextRow.cells[currentCol];
+ }
+ nextCell = nextRow.cells[nextColNum];
+ gCurrentCol[activeTableId] = nextColNum;
+ gCurerntCell = nextCell;
+ processMovement(prevCell, nextCell, bCtrlKey, activeTableId);
+
+ gFocusItem = nextCell;
+ setTimeout("doFocus()", 0);
+
+ }
+
+ } // end of if left
+ if (key == KEY_RIGHT ) { // right
+ nextColNum = currentCol + 1;
+ var prevCell = null;
+ if (currentRow >=0 ) {
+ nextRow = rows[currentRow];
+ if (nextRow != null && nextColNum < nextRow.cells.length) {
+ prevCell = nextRow.cells[currentCol];
+ nextCell = nextRow.cells[nextColNum];
+ gCurrentCol[activeTableId] = nextColNum;
+ gCurrentCell = nextCell;
+ processMovement(prevCell, nextCell, bCtrlKey, activeTableId);
+
+ gFocusItem = nextCell;
+ setTimeout("doFocus()", 0);
+ }
+ }
+
+
+ } // end of if right
+ bDefaultHandler = false;
+
+ if (nextCell != null) {
+ gCurrentCell[activeTableId]= nextCell;
+ }
+ } // end of if arrows
+ else if (key == KEY_SPACE && bCtrlKey) {
+ var currentCell = gCurrentCell[activeTableId];
+
+ var bSelected = toggleSelection(activeTableId,currentCell);
+ if (bSelected == "true") {
+ currentCell.className = "cellFocusSelect";
+ }
+ else {
+ currentCell.className = "cellFocus";
+ }
+
+ }
+ else if (key == KEY_ESCAPE) {
+ // pressing escape when editing a cell will end editng - this is not really what we want since
+ // it does not allow the escape to clear the input cell field first - I tried that in ignoreArrows() but
+ // could not get focus back to the cell after the escape.
+ if (gCurrentCell[activeTableId] != null) {
+ endEdit(gCurrentCell[activeTableId], false);
+ gFocusItem = gCurrentCell[activeTableId];
+ setTimeout("doFocus()",0);
+ bDefaultHandler = false;
+ }
+ }
+
+ else if (key == KEY_TAB && !evt.shiftKey ) {
+ // table is losing focus set the style of the current cell to cellBlur
+ gCurrentCell[activeTableId].className = "cellBlur";
+
+
+ }
+
+ } // end of try
+ catch (errorInfo) {
+ //alert(errorInfo);
+ }
+ return bDefaultHandler;
+}
+function processMovement(prevCell, nextCell, bCtrlKey, activeTableId) {
+ if (bCtrlKey == true) {
+ // leave prev cell in same state
+ // set style of prevCell to appropriate state
+ // set style of current cell to cellFocus
+ if (prevCell != null) {
+ var prevStyle = "";
+ if (prevCell.getAttribute("aria-selected") == "true" ) {
+ prevStyle = "cellSelect";
+ }
+ prevCell.className = prevStyle;
+ }
+ nextCell.className = "cellFocus";
+ gSelecting[activeTableId] = true;
+ }
+ else {
+ //bCtrlKey == false
+ // clear select on previous cell
+ // set style of previous cell to empty
+ // select current cell
+ // set style of current cell to cellFocusSelect
+ if (prevCell != null) {
+ removeSelection(activeTableId, prevCell);
+ prevCell.className = "";
+ }
+ addSelection(activeTableId, nextCell);
+ nextCell.className="cellFocusSelect";
+ }
+}
+
+function addSelection(activeTableId, currentCell) {
+ var selectedList = gSelectedCells[activeTableId];
+ var isSelected = currentCell.getAttribute("aria-selected");
+ if (isSelected != "true") {
+ // set selected and add to selection list
+ currentCell.setAttribute("aria-selected", "true");
+ selectedList[selectedList.length] = currentCell;
+ gSelectedCells[activeTableId] = selectedList;
+ }
+}
+
+function removeSelection(activeTableId, currentCell) {
+ var selectedList = gSelectedCells[activeTableId];
+ var isSelected = currentCell.getAttribute("aria-selected");
+ if (isSelected == "true" ) {
+ currentCell.removeAttribute("aria-selected");
+ // remove from list of selected cells
+ var idx = -1;
+ for (var j=0; j < selectedList.length; j++) {
+ if (selectedList[j] == currentCell) {
+ idx = j;
+ break;
+ }
+ }
+ if (idx <= 0) {
+ // remove the cell from the selected List
+ gSelectedCells[activeTableId] = selectedList.splice(idx,1,"");
+ }
+ }
+}
+function toggleSelection(activeTableId, currentCell) {
+// toggle selection of the cell
+ var selectedState = "";
+ var selectedList = gSelectedCells[activeTableId];
+ var isSelected = currentCell.getAttribute("aria-selected");
+ if (isSelected == "true" ) {
+ removeSelection(activeTableId, currentCell);
+
+ }
+ else {
+ addSelection(activeTableId,currentCell);
+ selectedState = "true"
+ }
+ return selectedState; // return current selection state of cell
+} // end of toggleSelection
+
+function clearSelected(activeTableId) {
+ // clear the selected cells
+ gSelecting[activeTableId] = false;
+ var selectedCells = gSelectedCells[activeTableId];
+ for (var k=0; k < selectedCells.length; k++) {
+ selectedCells[k].className = "";
+ selectedCells[k].setAttribute("aria-selected", "false");
+ }
+ gSelectedCells[activeTableId] = new Array(); // just create new, empty array
+} // end of clearSelected()
+
+function doClick(e,rowNum, colNum) {
+ /* put the doClick() in each TD element and pass the row and column number because it was the easiest way
to figure out what
+ row and column was clicked in both IE and Mozilla. Mozilla gives the element with the handler as the
currentTarget rather than the
+ actual element. For example, with onclick on the TABLE, Mozilla gives the event.currentTarget as the
TABLE when click on a cell.
+ IE gives the event.srcElement as the TD that was clicked on.
+ Also, could probably determine row and column programmatically if necessary rather than passing rowNum and
colNum. Or, pass the element itself!
+ */
+
+ var evt = (e != null) ? e : ((event) ? event : null); // Mozilla will include e parameter
+ var srcElem = findParentElem(evt,"table");
+ var activeTableId = srcElem.getAttribute("id");
+ var prevCell = gCurrentCell[activeTableId];
+ var rows = document.getElementById(activeTableId).rows;
+ var thisRow = rows[rowNum];
+ var thisCell = thisRow.cells[colNum];
+ // update the global variables for the clicked on cell
+ gCurrentCell[activeTableId] = thisCell;
+ gCurrentRow[activeTableId] = rowNum;
+ gCurrentCol[activeTableId] = colNum;
+ var bCtrlKey = evt.ctrlKey;
+ var bSameCell = (thisCell == prevCell);
+
+ if (gSelecting[activeTableId] == true && bCtrlKey == false) {
+ clearSelected(activeTableId);
+ }
+
+ if (bCtrlKey == false && !bSameCell) {
+ // remove selection from prev cell
+ // add this cell to selection
+ // set state of prev cell to empty
+ // set state of this cell to focusSelect
+ if (prevCell != null) {
+ removeSelection(activeTableId, prevCell);
+ prevCell.className = "";
+ }
+ addSelection(activeTableId, thisCell);
+ thisCell.className="cellFocusSelect";
+ }
+ else if (bCtrlKey == true && !bSameCell) {
+ // leave prev cell in same selection state
+ // update style of prev cell based on state
+ // add this cell to selection
+ // set this cell style to focusselect
+ if (prevCell != null) {
+ var prevStyle = "";
+ if (prevCell.getAttribute("aria-selected") == "true" ) {
+ prevStyle = "cellSelect";
+ }
+ prevCell.className = prevStyle;
+ }
+ addSelection(activeTableId, thisCell);
+ thisCell.className="cellFocusSelect";
+ gSelecting[activeTableId] = true;
+ }
+ else if (bCtrlKey == true && bSameCell) {
+ var bSelected = toggleSelection(activeTableId,thisCell);
+ if (bSelected == "true") {
+ thisCell.className = "cellFocusSelect";
+ }
+ else {
+ thisCell.className = "cellFocus";
+ }
+ }
+ gFocusItem = thisCell;
+ setTimeout("doFocus();", 0);
+
+} // end of doClick
+
+
+function doEvent(evtTarget, evtName, theEvent) {
+ if (evtTarget.fireEvent) {
+ // is IE, need "on" in front of event name
+ evtName = "on" + evtName;
+ evtTarget.fireEvent(evtName, theEvent);
+ }
+ else {
+ evtTarget.dispatchEvent(theEvent);
+ }
+ return;
+}
+
+
+function doLink(linkId) {
+ var theLink = document.getElementById(linkId);
+ var bTryAgain = false;
+ try {
+ theLink.click(); // for IE
+ } catch (clickError) {
+ bTryAgain = true;
+ }
+ if (bTryAgain) {
+ try {
+ var mClick = document.createEvent("MouseEvents");
+ mClick.initEvent("click",true, true);
+ theLink.dispatchEvent(mClick);
+ } catch (e) {
+ alert(e.message); //+ "DEBUG: can't fire event to link element");
+ }
+ }
+
+ return false;
+}
+
+function doEdit(event, parentCell, colNumber) {
+// edit a spreadsheet cell. Find text node of cell and store data. Create an input field and label and
add to cell; set text node value into cell; remove text node;
+ if (parentCell.getAttribute("aria-readonly") =="true") {
+ return;
+ }
+ if (parentCell.editMode != "true") {
+ var inputId = "col" + colNumber;
+ var inputField = document.createElement("input");
+ setStyle(inputField, "border", "0", "");
+ inputField.setAttribute("id", inputId);
+ var dataNode = null;
+ var editData = "";
+ if (parentCell.hasChildNodes() ) {
+ // TODO find parentCells text node - for now just assuming it is first child
+ dataNode = parentCell.firstChild;
+ parentCell.removeChild(dataNode);
+ editData = dataNode.data;
+ }
+ parentCell.saveData = editData;
+ parentCell.appendChild(inputField);
+ inputField.setAttribute("value",editData);
+ setStyle(inputField,"width", "100%","");
+ try {
+ inputField.addEventListener("blur",checkEdit, true);
+ inputField.addEventListener("keydown", ignoreArrows,true); // process arrow key input so it does not
get up to parent table onkeydown
+ }
+ catch (ex) { // IE
+ inputField.attachEvent('blur',checkEdit, true);
+ inputField.attachEvent('keydown', ignoreArrows, true);
+ }
+
+ // create label for the cell - use the columnheader as the label
+ var parentTable = findParent(parentCell, "table");
+ var colHeader = parentTable.rows[0].cells[colNumber];
+ inputField.setAttribute("aria-labelledby", colHeader.id);
+
+ parentCell.editMode = "true";
+ // set focus to the input field
+ gFocusItem=inputField;
+ setTimeout("doFocus()", 0);
+ } // end of if edit
+ else {
+ endEdit(parentCell,true);
+
+ gFocusItem = parentCell;
+ setTimeout("doFocus()",0);
+
+ } // end of else end edit
+
+
+} // end of doEdit()
+
+function endEdit(parentCell, bSave) {
+// end editing remove input node, remove label node
+// currently VERY dependent upon the organization of the DOM
+// cell is in edit mode - store data and leave edit mode
+ // find the input field
+ if (parentCell.hasChildNodes() && parentCell.editMode == "true") {
+ var inputNode = findChildNode(parentCell,"input");
+ /*var inputNode = parentCell.firstChild; // TODO should never be null but wrap in a try/catch
+ var childNodeName = inputNode.nodeName
+ childNodeName.toLowerCase();
+ while (childNodeName != "input" && inputNode != null) {
+ inputNode = inputNode.nextSibling;
+ childNodeName = inputNode.nodeName.toLowerCase();
+ }*/
+ if (inputNode != null) {
+ var storeData = parentCell.saveData;
+ if (bSave == true) {
+ storeData = inputNode.value;
+ }
+ // remove event listenters
+ try {
+ inputNode.removeEventListener("blur",checkEdit,true);
+ inputNode.removeEventListener("keydown", ignoreArrows, true);
+ }
+ catch (ex) {
+ inputField.detachEvent('blur',checkEdit, true);
+ inputField.detachEvent('keydown', ignoreArrows, true);
+ }
+
+ parentCell.removeChild(inputNode);
+ var labelNode = findChildNode(parentCell, "label");
+ if (labelNode != null) {
+ parentCell.removeChild(labelNode);
+ }
+ var newDataNode = document.createTextNode(storeData);
+ parentCell.appendChild(newDataNode);
+ parentCell.editMode="false";
+ }
+ }
+} // end of endEdit
+
+function findChildNode(startNode, nodeName) {
+// TODO - currently only searchs siblings of startNode - does not recurse
+ var foundNode = null;
+ try {
+ if (startNode.hasChildNodes() ) {
+ var testNode = startNode.firstChild;
+ while (testNode != null && (testNode.nodeName.toLowerCase() != nodeName)) {
+ testNode = testNode.nextSibling;
+ }
+ foundNode = testNode;
+ }
+ } catch (error) {
+ alert("DEBUG - error in findChildNode() - " + error.message);
+ foundNode = null;
+ }
+ return foundNode;
+}
+
+function checkEdit(event) {
+try {
+ var srcElem = findParentElem(event,"table");
+ var currentCell = gCurrentCell[srcElem.id];
+ var parentCell = findParentElem(event,"td");
+ if (parentCell == currentCell) {
+ if (parentCell && parentCell.editMode == "true") {
+ endEdit(parentCell,true);
+ }
+
+ gFocusItem = srcElem;
+ setTimeout("doFocus();", 0);
+ }
+} catch (e) {
+ alert("DEBUG - error in checkEdit: " + e.message);
+}
+}
+
+function ignoreArrows(event) {
+ var eventTarget = event.target;
+ var key = event.keyCode;
+ bEventContinue = true; // let input field handle the key
+ if (key >=KEY_LEFT && key <= KEY_DOWN) {
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ else {
+ event.cancelBubble = true;
+ }
+ }
+ /* This does not work - I can not get focus back into the cell after the escape!!!
+ else if (key == KEY_ESCAPE) {
+ // first let escape be used to clear the cell, if cell is empty end editing
+ if (eventTarget.value == "") {
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ else {
+ event.cancelBubble = true;
+ }
+ var srcElem = findParentElem(event,"table");
+ var currentCell = gCurrentCell[srcElem.id];
+ var parentCell = findParentElem(event,"td");
+ if (parentCell == currentCell) {
+ if (parentCell && parentCell.editMode == "true") {
+ endEdit(parentCell,false);
+ }
+
+ }
+ // focus the table - that will focus the currentCell
+ gFocusItem = srcElem;
+ setTimeout("doFocus();", 0);
+
+ }
+
+ } */
+
+
+} // end of ignoreArrows
+function setCell(tableId) {
+ var currentCell = gCurrentCell[tableId];
+ if (currentCell == null) {
+ // no cell selected, set it to first cell
+ var grid = document.getElementById(tableId);
+ var rows = grid.rows;
+ var firstRow = rows[0];
+ currentCell = firstRow.cells[0];
+ gCurrentRow[tableId] = 0;
+ gCurrentCol[tableId] = 0;
+ gCurrentCell[tableId] = currentCell;
+
+ }
+ currentCell.className="cellFocusSelect";
+ gFocusItem = currentCell;
+ setTimeout("doFocus()", 0);
+
+}
+
+// would like to change the style of the cell when focus leaves the table completely but not sure how to
implement since table gets onblur when each cell loses focus
+function blurCell(event, tableId) {
+ var currentCell = gCurrentCell[tableId];
+ if (currentCell != null) {
+ currentCell.className="cellBlur";
+ }
+
+ // else do nothing
+}
+
+// very specific function to change the styles on the page
+function doColor(colorScheme) {
+
+ // get the styles
+ var oSS = pageGetStyleSheet("basic", null);
+ var ssRules = cssGetRules(oSS);
+
+ var colorArray;
+ if (ssRules != null) {
+ switch(colorScheme) {
+ case "grey":
+ colorArray = new Array("#C0C0C0","#F5F5F5","#999999","#F5F5F5");
+ changeColors(ssRules, colorArray);
+ break;
+ case "blues":
+ colorArray = new Array("#00CED1", "#B0E0E6","#000080","#E0FFFF");
+ changeColors(ssRules, colorArray);
+ break;
+ case "green":
+ colorArray = new Array("#3CB371","#90EE90","#008000","#F0FFF0");
+ changeColors(ssRules, colorArray);
+ break;
+ case "rose":
+ colorArray = new Array("#CD5C5C","#F08080","#800000","#FFE4E1");
+ changeColors(ssRules, colorArray);
+ default:
+ // do nothing
+ break;
+ } // end switch
+ }
+
+ return false; // do not propagate
+}
+function changeColors(ssRules, colorArray) {
+ var theRule;
+ // menubar background-color
+ theRule = cssGetRule(ssRules, "menubar");
+ changeStyleRule(theRule, "background-color", colorArray[0]);
+ // menu background-color
+ theRule = cssGetRule(ssRules, "menu");
+ changeStyleRule(theRule, "background-color", colorArray[0]);
+ theRule = cssGetRule(ssRules,"topMenu");
+ changeStyleRule(theRule, "border-color", colorArray[0]);
+ changeStyleRule(theRule, "background-color", colorArray[0]);
+ theRule = cssGetRule(ssRules, "cellFocusSelect");
+ changeStyleRule(theRule, "background-color", colorArray[0]);
+ theRule = cssGetRule(ssRules, "table");
+ changeStyleRule(theRule, "border-color", colorArray[0]);
+ theRule = cssGetRule(ssRules, "menudrop");
+ changeStyleRule(theRule, "background-color", colorArray[1]);
+ changeStyleRule(theRule, "border-color",colorArray[1]);
+ theRule = cssGetRule(ssRules, "cellSelect");
+ changeStyleRule(theRule, "background-color", colorArray[3]);
+ theRule = cssGetRule(ssRules, "topMenu:focus");
+ changeStyleRule(theRule, "border-color", colorArray[2]);
+ changeStyleRule(theRule, "background-color", colorArray[2]);
+ theRule = cssGetRule(ssRules, "topMenu:hover");
+ changeStyleRule(theRule, "border-color", colorArray[2]);
+ changeStyleRule(theRule, "background-color", colorArray[2]);
+ theRule = cssGetRule(ssRules, "menuitem:focus");
+ changeStyleRule(theRule, "border-color", colorArray[2]);
+ changeStyleRule(theRule, "background-color", colorArray[2]);
+ theRule = cssGetRule(ssRules, "menuitem:hover");
+ changeStyleRule(theRule, "border-color", colorArray[2]);
+ changeStyleRule(theRule, "background-color", colorArray[2]);
+ //theRule = cssGetRule(ssRules, "action");
+ //changeStyleRule(theRule, "color", colorArray[2]);
+ theRule = cssGetRule(ssRules, "cellBlur");
+ changeStyleRule(theRule, "backgournd-color", colorArray[3]);
+
+
+
+}
+function doTotals(tableId, key) {
+// simple function to do some totaling of information in the table
+// hard coded to the format of this particular table (i.e. for demo purposes only - NOT general purpose)
+// id of the table containing the data
+// keyName - item name we are totaling
+// column numbers are hard coded
+
+var DATE_COL = 1;
+var EXPENSE_COL = 2;
+var display= "no results";
+var results;
+bEventContinue = false;
+try {
+ var activeTable = document.getElementById(tableId);
+ var tableRows = activeTable.rows;
+
+ //var prevRow = rows[currentRow];
+ // prevCell = prevRow.cells[currentCol];
+ var lcKey = key.toLowerCase();
+ if (lcKey == "date") {
+ display = "";
+ var exception = "";
+ var dates = new Array();
+ // find all unique dates then total each
+ for(var i=1; i<tableRows.length; i++) {
+ exception=""; //reset
+ var bFound = false;
+ var dateCell = tableRows[i].cells[DATE_COL];
+ if (dateCell.firstChild && dateCell.firstChild.data) {
+ var cellData =dateCell.firstChild.data;
+ if (i == 1) {
+ // first cell - force adding date to array
+ bFound = false;
+ }
+ else {
+ // see if date already exists in array
+ for(var j=0; j<dates.length; j++) {
+ if (dates[j] == cellData) {
+ bFound = true;
+ break;
+ }
+ }
+ } // end of else
+ if (bFound == false) {
+ dates[dates.length] = cellData;
+ results = getData(tableRows,cellData,DATE_COL);
+ if (results.length > 0) {
+ var total = calcTotal(results);
+ if (total > 1000) {
+ exception = " !!! EXCEPTION: daily total over $1000 !!!"
+ }
+ display += "Total for " + cellData + " is $" + total + exception + "\n";
+
+ }
+ }
+ } // end of if celldata
+ } // end of for
+ } // end of if date
+ else {
+ results = getData(tableRows,lcKey,EXPENSE_COL);
+ if (results.length > 0) {
+ var total = calcTotal(results);
+ display = "Total for " + key + " is $" + total;
+ }
+ }
+
+ gAlertString = display;
+ setTimeout("delayedAlert(gAlertString);",0);
+
+} catch (error) {
+ alert("DEBUG- error in doTotals() " + error.message);
+ bEventContinue = true;
+}
+ return bEventContinue;
+}
+function getData(tableRows,lcKey, colNum) {
+// find all rows that contain key and store amount contents in array
+var AMOUNT_COL = 3;
+ var results = new Array();
+ for (var i=1; i<tableRows.length; i++) {
+ var keyCell = tableRows[i].cells[colNum];
+ if (keyCell.firstChild && keyCell.firstChild.data) {
+ var cellData =keyCell.firstChild.data;
+ cellData = cellData.toLowerCase();
+ if (cellData.indexOf(lcKey) > -1) {
+ var amtCell = tableRows[i].cells[AMOUNT_COL];
+ var data = amtCell.firstChild.data; // lots of assumptions here!!!
+ results[results.length] = data;
+ }
+ }
+ }
+ return results;
+}
+function calcTotal(results) {
+ // results is array of strings to total - may have $
+ var total =0;
+ for (var i=0; i < results.length; i++) {
+ var value = null;
+ var amt = results[i];
+ var idx = amt.indexOf('$');
+ if (idx > -1) {
+ amt = amt.substring(idx+1); // assumes only one $ and it is at the beginning
+ }
+ value = parseFloat(amt, 10);
+ if (value != NaN) {
+ total += value;
+ }
+ }
+ return total.toFixed(2);
+}
+
+
+
+
+-->
+</script>
+<style type="text/css" id="basic" title="basic">
+table {
+ empty-cells:show;
+ border-collapse: collapse; // Show empty table cells in IE
+}
+
+.menubar {
+ background-color:#C0C0C0;
+}
+.menu {
+ float:left;
+ width:5em;
+ padding:1px 3px;
+ background-color:#C0C0C0;
+ color:black;
+
+}
+.menudrop {
+ display:none;
+ background-color:#F5F5F5;
+ width:150%;
+ border: solid #999999 1px;
+
+
+}
+.menusub {
+ display:none;
+ background-color:#F5F5F5;
+ border:solid #999999 1px;
+ position:absolute;
+ width:25%;
+}
+
+.content {
+ margin-top:2em;
+ position:absolute;
+ clear:both;
+
+}
+.topMenu {
+ border-style:solid;
+ border-color:#C0C0C0;
+ border-width:1px;
+ background-color:#C0C0C0;
+}
+
+.topMenu:focus {
+ background-color:#999999;
+ border-style:dashed;
+ border-color:#999999;
+ border-width:1px;
+ color:white;
+}
+.topMenu:hover {
+ background-color:#999999;
+ border-style:dashed;
+ border-color:#999999;
+ border-width:1px;
+ color:white;
+}
+
+.menuitem {
+ border-style:solid;
+ border-color:#F5F5F5;
+ border-width:1px; /*color must be the same as background color (which is inherited from .menudrop) */
+ text-align:justify;
+}
+.menuitem:focus {
+ color:white;
+ background-color:#999999;
+ border-style:dashed;
+ border-color:#999999;
+ border-width:1px;
+
+}
+.menuitem:hover {
+ background-color:#999999;
+ border-style:dashed;
+ border-color:#999999;
+ border-width:1px;
+ color:white;
+
+}
+.menuitem[aria-disabled="true"] {
+ color:#666666;
+}
+.rowSelected {
+ background-color:#66CCCC;
+
+}
+td[aria-readonly="true"] {
+ color:#666666;
+}
+.cellFocusSelect {
+ background-color:#CCCCCC;
+ outline: 1px dashed green;
+
+}
+.cellFocus {
+ outline: 1px dashed green;
+}
+
+.cellSelect {
+ background-color:#DCDCDC;
+}
+.cellBlur {
+ border-width:1px ;
+ border-style:dotted;
+ border-color:#999999;
+ background-color:#F5F5F5;
+}
+table, th, td {
+
+ border-width:2px;
+ border-style:groove;
+ border-color:#CCCCCC;
+
+}
+
+.action {
+ color:#0000FF;
+ text-decoration:underline;
+}
+a:visited {
+ color:#000066;
+}
+
+.leftCellHi {
+ border-left:2px dotted #00FF00;
+ border-top:2px dotted #00FF00;
+ border-bottom:2px dotted #00FF00;
+}
+.middleCellHi {
+ border-top:2px dotted #00FF00;
+ border-bottom:2px dotted #00FF00;
+}
+
+.rightCellHi {
+ border-right:2px dotted #00FF00;
+ border-top:2px dotted #00FF00;
+ border-bottom:2px dotted #00FF00;
+}
+.nosize {
+ position:absolute;
+ width:0px;
+ height:0px;
+ overflow:hidden;
+}
+
+
+</style>
+
+<style type="text/css"></style></head>
+<body onkeydown="topMenu.doMenu(event);" role="application" onload="gFocusItem =
document.getElementById('table2'); setTimeout('doFocus();',0); ">
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h1>Accessible Widgets </h1>
+
+
+<div style="position:absolute;z-index:2;">
+<div id="theMenuBar" class="menubar" role="menubar" onkeydown="return topMenu.doNavigation(event);"
tabindex="-1">
+ <div class="menu" id="edit" onclick="topMenu.showMenu(event, this.id, false);" onkeydown="if
(event.keyCode == 13 ) {topMenu.showMenu(event, this.id, true);}"
onmouseover="topMenu.showMenu(event,this.id,false);" onmouseout="topMenu.hideMenu(event);">
+ <div tabindex="-1" role="menuitem" aria-haspopup="true" id="edittop" class="topMenu">Edit</div>
+ <div class="menudrop" role="menu" id="editItems">
+ <div id="cut" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'do Cut');" onkeydown="if (event.keyCode == 13) {topMenu.doAlert(event,this,'do
cut');}" onmouseover="topMenu.focusItem(event,0,0);">Cut</div>
+ <div id="copy" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'do Copy');" onkeydown="if (event.keyCode == 13) {topMenu.doAlert(event,this,'do
copy');}" onmouseover="topMenu.focusItem(event,0,1);">Copy</div>
+ <div id="paste" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'do Paste');" onkeydown="if (event.keyCode == 13) {topMenu.doAlert(event,this,'do
paste');}" onmouseover="topMenu.focusItem(event,0,1);">Paste</div>
+ </div>
+ </div>
+ <div class="menu" id="2" onclick="topMenu.showMenu(event, this.id,false);" onkeydown="if (event.keyCode ==
13 ) {topMenu.showMenu(event, this.id, true);}" onmouseover="topMenu.showMenu(event,this.id,false);"
onmouseout="topMenu.hideMenu(event);">
+ <div tabindex="-1" role="menuitem" aria-haspopup="true" id="2top" class="topMenu">View</div>
+ <div class="menudrop" role="menu" id="2Items" style="display:none;">
+ <div tabindex="-1" role="menuitem" aria-haspopup="true" id="2.1sub" class="menuitem" onkeydown="if
(event.keyCode == 13 ) {return topMenu.showSubMenu(event,this.id);}">Themes
></div>
+ <div class="menusub" role="menu" id="2.1subItems" style="display:none;">
+ <div id="2.1.1" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doActionColor(event,'grey');" onkeydown="if (event.keyCode == 13) {return
topMenu.doActionColor(event,'grey');}">Basic Grey </div>
+ <div id="2.1.2" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doActionColor(event,'blues');" onkeydown="if (event.keyCode == 13) {return
topMenu.doActionColor(event,'blues');}">The Blues</div>
+ <div id="2.1.3" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doActionColor(event,'green');" onkeydown="if (event.keyCode == 13) {return
topMenu.doActionColor(event,'green');}">Garden</div>
+ <div id="2.1.4" tabindex="-1" role="menuitem" class="menuitem" aria-disabled="true"
onclick="return topMenu.doAlert(event,this,'do Item4');" onkeydown="if (event.keyCode == 13) {return
topMenu.doActionColor(event,'pink');}">In the Pink</div>
+ <div id="2.1.5" tabindex="-1" role="menuitem" class="menuitem" oonclick="return
topMenu.doActionColor(event,'rose');" onkeydown="if (event.keyCode == 13) {return
topMenu.doActionColor(event,'rose');}">Rose </div>
+ </div><!-- end themes sub menu items -->
+ <div tabindex="-1" role="menuitem" class="menuitem" id="2.2">Hide</div>
+ <div tabindex="-1" role="menuitem" class="menuitem" id="2.3">Show</div>
+ <div tabindex="-1" role="menuitem" aria-haspopup="true" id="2.4sub" class="menuitem" onclick="return
topMenu.showSubMenu(event,this.id);" onkeydown="if (event.keyCode == 13 ) {return
topMenu.showSubMenu(event,this.id);}">More
></div>
+ <!--<div tabindex="-1" role="menuitem" class="menuitem" id="2.4sub" onclick="return
topMenu.showSubMenu(event,this.id);" onkeydown="if (event.keyCode == 13 ) {return
topMenu.showSubMenu(event,this.id);}">More
></div> -->
+ <div class="menusub" role="menu" id="2.4subItems" style="display:none">
+ <div id="2.4.1" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'do Something 1');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'doSomething 1');}">one </div>
+ <div id="2.4.2" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'do Something 2');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'doSomething 2');}">two</div>
+ </div> <!-- end of more sub menu -->
+ </div><!-- end View drop menu -->
+ </div>
+ <div class="menu" id="3" onclick="topMenu.showMenu(event, this.id,false);" onkeydown="if (event.keyCode ==
13 ) {topMenu.showMenu(event, this.id, true);}" onmouseover="topMenu.showMenu(event,this.id,false);"
onmouseout="topMenu.hideMenu(event);">
+ <div tabindex="-1" role="menuitem" aria-haspopup="true" id="3top" class="topMenu">Tools</div>
+ <div class="menudrop" role="menu" id="3Items" style="display:none;">
+ <div id="3.1" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'do spell check');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'do spell check');}">Spelling...</div>
+ <div id="3.2" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'do error checking');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'do error checking');}">Error Checking...</div>
+ <div id="3.3sub" tabindex="-1" role="menuitem" aria-haspopup="true" class="menuitem"
onclick="return topMenu.showSubMenu(event,this.id);;" onkeydown="if (event.keyCode == 13) {return
topMenu.showSubMenu(event,this.id);}">Show Rows ></div>
+ <div class="menusub" role="menu" id="3.3subItems" style="display:none">
+ <div id="3.3.1" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'highlight even rows');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'highlight even rows');}">even</div>
+ <div id="3.3.2" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'highlight odd rows');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'hghlight odd rows');}">odd</div>
+ <div id="3.3.3" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'highlight all rows');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'highlight all rows');}">all</div>
+ </div> <!-- end of more sub menu -->
+ <div id="3.4" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'do Options');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'do Options');}">Options... </div>
+ </div>
+ </div>
+ <div class="menu" id="four" onclick="topMenu.showMenu(event, this.id,false);" onkeydown="if (event.keyCode
== 13 ) {topMenu.showMenu(event, this.id, true);}" onmouseover="topMenu.showMenu(event,this.id,false);"
onmouseout="topMenu.hideMenu(event);">
+ <div tabindex="-1" role="menuitem" aria-haspopup="true" id="fourtop" class="topMenu">Totals</div>
+ <div class="menudrop" role="menu" id="fourItems" style="display:none;">
+ <div id="4.1" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doActionTotal(event,'table2','lodging');" onkeydown="if (event.keyCode == 13) {return
topMenu.doActionTotal(event,'table2','lodging');}">Lodging </div>
+ <div id="4.2" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doActionTotal(event,'table2','breakfast');" onkeydown="if (event.keyCode == 13) {return
topMenu.doActionTotal(event,'table2','breakfast');}">Breakfast </div>
+ <div id="4.3" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doActionTotal(event,'table2','lunch');" onkeydown="if (event.keyCode == 13) {return
topMenu.doActionTotal(event,'table2','lunch');}">Lunch </div>
+ <div id="4.4" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doActionTotal(event,'table2','dinner');" onkeydown="if (event.keyCode == 13) {return
topMenu.doActionTotal(event,'table2','dinner');}">Dinner </div>
+ <div id="4.5" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doActionTotal(event,'table2','date');" onkeydown="if (event.keyCode == 13) {return
topMenu.doActionTotal(event,'table2','date');}">By Date </div>
+ </div>
+ </div>
+ <div class="menu" id="five" onclick="topMenu.showMenu(event, this.id,false);" onkeydown="if (event.keyCode
== 13 ) {topMenu.showMenu(event, this.id, true);}" onmouseover="topMenu.showMenu(event,this.id,false);"
onmouseout="topMenu.hideMenu(event);">
+ <div tabindex="-1" role="menuitem" aria-haspopup="true" id="fivetop" class="topMenu">Help</div>
+ <div class="menudrop" role="menu" id="fiveItems" style="display:none;">
+ <div id="5.1" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'Show Help Index');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'Show Help index');}">Help Index</div>
+ <div id="5.2" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'Show navigation help');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'Show navigation help');}">Navigation Help</div>
+ <div id="5.3" tabindex="-1" role="menuitem" class="menuitem" onclick="return
topMenu.doAlert(event,this,'DHTML roadmap Example, March 2005');" onkeydown="if (event.keyCode == 13)
{topMenu.doAlert(event,this,'DHTML Roadmap example, March 2005');}">About</div>
+
+ </div>
+ </div>
+</div>
+</div>
+
+<div class="content">
+<div style="height:20em; overflow:auto;">
+<table tabindex="0" border="2" cellspacing="0" id="table2" role="grid" onkeydown=" return
doTableKeys(event);" onfocus="setCell(this.id);">
+<thead>
+<tr>
+ <th tabindex="-1" role="columnheader" id="colhead1" style="width:6em" onclick="doClick(event,0,0);"
onkeydown="if (event.keyCode==13) {return doLink('aEntry');}" class="cellFocusSelect"><span class="action"
title="Sort by Entry #" onclick="alert('sort column on click');" tabindex="-1" id="aEntry">Entry #</span></th>
+ <th tabindex="-1" role="columnheader" id="colhead2" onclick="doClick(event,0,1);" onkeydown="if
(event.keyCode==13) {return doLink('aDate');}" style="width:10em"><span class="action" title="Sort by Date"
onclick="alert('sort column on click');" tabindex="-1" id="aDate">Date</span></th>
+ <th tabindex="-1" role="columnheader" id="colhead3" onclick="doClick(event,0,2);" onkeydown="if
(event.keyCode==13) {return doLink('aExpense');}" style="width:20em"><span class="action" title="Sort by
Expense Name" onclick="alert('sort column on click');" tabindex="-1" id="aExpense">Expense</span></th>
+ <th tabindex="-1" role="columnheader" id="colhead4" onclick="doClick(event,0,3);" onkeydown="if
(event.keyCode==13) {return doLink('aAmount');}" style="width:8em"><span class="action" title="Sort by
Amount" onclick="alert('sort column on click');" tabindex="-1" id="aAmount">Amount</span></th>
+ <th tabindex="-1" role="columnheader" id="colhead5" onclick="doClick(event,0,4);" onkeydown="if
(event.keyCode==13) {return doLink('aMerchant');}" style="width:15em"><span class="action" title="Sort by
Merchant" onclick="alert('sort column on click');" tabindex="-1" id="aMerchant">Merchant</span></th>
+ <th tabindex="-1" role="columnheader" id="colhead6" style="width:8em"><span>Type</span></th>
+
+</tr>
+</thead>
+<tbody>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,1,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">1</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" id="testCell" onclick="doClick(event,1,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}">03/14/05</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,1,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}">Conference Fee</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,1,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}">$449.00</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,1,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}">CSUN Center on Disability</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,1,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}">credit</td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,2,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">2</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,2,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}">03/15/05</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,2,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}">lodging</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,2,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}">$119.00</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,2,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}">LAX Hilton</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,2,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}">credit</td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,3,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">3</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,3,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}">03/15/05</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,3,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}">dinner</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,3,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}">$24.00</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,3,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}">Chili's</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,3,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}">cash</td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,4,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">4</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,4,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}">03/16/05</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,4,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}">lodging</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,4,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}">$119.00</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,4,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}">LAX Hilton</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,4,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}">credit</td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,5,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">5</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,5,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}">03/16/05</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,5,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}">breakfast</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,5,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}">$6.50</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,5,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}">Starbucks</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,5,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}">cash</td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,6,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">6</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,6,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}">03/16/05</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,6,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}">lunch</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,6,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}">$9.35</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,6,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}">Super Sub Stop</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,6,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}">cash</td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,7,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">7</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,7,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}">03/16/05</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,7,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}">dinner</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,7,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}">$40.00</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,7,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}">Davio's</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,7,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}">credit</td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,8,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">8</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,8,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,8,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,8,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,8,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,8,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,9,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">9</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,9,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,9,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,9,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,9,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,9,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,10,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">10</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,10,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,10,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,10,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,10,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,10,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,11,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">11</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,11,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,11,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,11,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,11,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,11,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,12,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">12</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,12,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,12,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,12,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,12,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,12,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,13,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">13</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,13,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,13,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,13,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,13,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,13,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,14,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">14</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,14,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,14,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,14,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,14,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,14,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,15,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">15</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,15,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,15,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,15,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,15,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,15,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,16,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">16</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,16,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,16,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,16,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,16,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,16,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,17,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">17</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,17,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,17,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,17,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,17,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,17,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+<tr>
+ <td tabindex="-1" role="rowheader" aria-readonly="true" onclick="doClick(event,18,0);"
ondblclick="doEdit(event,this,0);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,0);return
false;}">18</td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,18,1);"
ondblclick="doEdit(event,this,1);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,1);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,18,2);"
ondblclick="doEdit(event,this,2);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,2);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,18,3);"
ondblclick="doEdit(event,this,3);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,3);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,18,4);"
ondblclick="doEdit(event,this,4);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,4);return
false;}"></td>
+ <td tabindex="-1" role="gridcell" aria-selected="false" onclick="doClick(event,18,5);"
ondblclick="doEdit(event,this,5);" onkeydown="if (event.keyCode == 13) { doEdit(event,this,5);return
false;}"></td>
+</tr>
+</tbody>
+</table>
+</div>
+</form>
+</div>
+</body>
+</html>
diff --git a/test/html/aria-tabpanel.html b/test/html/aria-tabpanel.html
new file mode 100644
index 0000000..8950248
--- /dev/null
+++ b/test/html/aria-tabpanel.html
@@ -0,0 +1,263 @@
+<html>
+<head>
+<title>Tabbed UI</title>
+<style type="text/css">
+.tab {
+ color: navy;
+ background-color: lightgrey;
+ border: thin solid navy;
+ text-align: center;
+ font: 9pt Verdana,sans-serif;
+ padding: 4px;
+ padding-left: 2em;
+ padding-right: 2em;
+}
+
+.tabActive {
+ color:black;
+ font-weight:bold;
+ border:thin dashed black;
+ background-color: beige;
+ border-bottom: thin solid beige;
+ border-left: thin solid navy;
+ border-top: thin solid navy;
+ border-right: thin solid navy;
+}
+
+div[aria-hidden="true"] { display: none; }
+
+.panel {
+ position: relative;
+ top: 3px;
+ background-color: beige;
+ color: navy;
+ width: 95%;
+ height: 85%;
+ font: 12pt Verdana,sans-serif;
+ border: thin solid navy;
+ padding: 10px;
+ overflow: auto;
+}
+
+</style>
+
+<script>
+<!--
+// global to store the item to be focused
+gFocusItem = null;
+
+function doFocus()
+{
+ if (gFocusItem != null) {
+ gFocusItem.focus();
+ gFocusItem=null;
+ }
+}
+
+var KEY_UP = 38;
+var KEY_DOWN = 40;
+var KEY_LEFT = 37;
+var KEY_RIGHT = 39;
+var KEY_ESCAPE = 27;
+var KEY_M = 77;
+var KEY_F10 = 121;
+var KEY_SPACE = 32;
+var KEY_TAB = 9;
+var KEY_PAGEUP = 33;
+var KEY_PAGEDOWN = 34;
+
+// globals to store current tab information
+var gCurrentTabNum = -1;
+var gNumTabs = 5;
+
+function selectTab(nextTabNum)
+{
+ var newTab = document.getElementById("tab" + nextTabNum);
+ gFocusItem = newTab;
+ setTimeout("doFocus()", 0);
+}
+
+function doNavigation(event)
+{
+ var key = event.keyCode; //alert(key);
+ var bEventContinue = true;
+ var nextTabNum;
+ var bDoNextTab = true; // requires less code if init to true
+ var bCtrlKey = event.ctrlKey;
+ var bAltKey = event.altKey;
+ var direction = 0;
+ var bCycle = false;
+ if ((key == KEY_LEFT || key == KEY_RIGHT) && !bAltKey) {
+ bCycle = false;
+ bEventContinue = false;
+ if (key == KEY_RIGHT) {
+ direction = 1;
+ }
+ else if (key == KEY_LEFT) {
+ direction = -1;
+ }
+ }
+ else if (bCtrlKey && event.shiftKey) {
+ bCycle = true; //ctrl-shift-pageup, ctrl-shift-pagedown,
+ switch (key) {
+ case KEY_PAGEUP:
+ direction = -1;
+ break;
+ case KEY_PAGEDOWN:
+ direction = 1;
+ break;
+ default:
+ bDoNextTab = false;
+ break;
+ } // end switch
+ } // end of if ctrlKey and shiftKey
+ else {
+ // not a key we care about
+ bDoNextTab = false;
+ }
+
+ if (bDoNextTab == true) {
+ if (direction > 0) {
+ nextTabNum = gCurrentTabNum + 1;
+ }
+ else if (direction < 0) {
+ nextTabNum = gCurrentTabNum -1;
+ }
+ if (nextTabNum == gNumTabs && bCycle == true) {
+ nextTabNum = 0;
+ }
+ else if (nextTabNum < 0 && bCycle == true) {
+ nextTabNum = gNumTabs -1;
+ }
+ else if ((nextTabNum == gNumTabs || nextTabNum < 0) && bCycle == false) {
+ bDoNextTab = false; // do nothing
+ }
+ // test again - last section may have changed value of bDoNextTab
+ if (bDoNextTab == true) {
+ selectTab(nextTabNum);
+ }
+ }
+
+ return bEventContinue;
+}
+
+function handleFocus(event)
+{
+ var newTab = event.target;
+ if (newTab.getAttribute("role") != "tab")
+ return;
+
+ newTabNum = parseInt(newTab.id.charAt(3));
+ if (newTabNum == gCurrentTabNum)
+ return;
+
+ if (gCurrentTabNum >= 0) {
+ var curTab = document.getElementById("tab" + gCurrentTabNum);
+ var curPanel = document.getElementById("panel" + gCurrentTabNum);
+ curPanel.setAttribute("aria-hidden", "true");
+ curPanel.className += ""; // Force refresh of attribute selectors
+ curTab.setAttribute("class", "tab");
+ curTab.tabIndex = "-1";
+ }
+
+ var newTab = document.getElementById("tab" + newTabNum);
+ var newPanel = document.getElementById("panel" + newTabNum);
+ newPanel.removeAttribute("aria-hidden");
+ newPanel.className += ""; // Force refresh of attribute selectors
+ newTab.setAttribute("class", "tab tabActive");
+ newTab.tabIndex = "0";
+
+ gCurrentTabNum = newTabNum;
+}
+
+-->
+</script>
+<style type="text/css"></style></head>
+<body onload="selectTab(0);">
+<div role="tablist" onkeydown="return doNavigation(event);">
+ <span id="tab0" tabindex="0" class="tab tabActive" role="tab" onclick="selectTab(0);"
onfocus="handleFocus(event);">
+ Tab Zero
+ </span>
+ <span id="tab1" tabindex="-1" class="tab" role="tab" onclick="selectTab(1);" onfocus="handleFocus(event);">
+ Tab One
+ </span>
+ <span id="tab2" tabindex="-1" class="tab" role="tab" onclick="selectTab(2);" onfocus="handleFocus(event);">
+ Tab Two
+ </span>
+ <span id="tab3" tabindex="-1" class="tab" role="tab" onclick="selectTab(3);" onfocus="handleFocus(event);">
+ Tab Three
+ </span>
+ <span id="tab4" tabindex="-1" class="tab" role="tab" onclick="selectTab(4);" onfocus="handleFocus(event);">
+ Tab Four
+ </span>
+</div>
+
+<div id="tabpanels" role="presentation">
+ <div id="panel0" class="panel" tabindex="-1" role="tabpanel" aria-labelledby="tab0">
+ <span>Panel 0</span>
+ <p>This example requires Firefox 3 or later to work with screen readers -- it
+ uses ARIA properties without namespaces, which is now the correct
+ markup.</p>
+ <div>Use tab key to reach the tab. Once a tab has focus use:
+ <ul>
+ <li>left and right arrows to move from tab to tab. Panel is made visible when
+ tab gets focus. Arrow keys do not cycle around the tabs</li>
+ <li>ctrl-left and ctrl-right arrows behave the same as left and right arrows</li>
+ <li>ctrl-shift-pageup / ctrl-shift-pagedown is the same as left and right arrows but WILL
+ cycle around the tab order (shift was added as a modifier so as not to
+ conflict with the Firefox tabbing keys)</li>
+ <li>Ctrl-shift-tab /ctrl-tab are not implemented since these keys conflict with browser tab
switching keys.</li>
+ </ul>
+ </div>
+ </div>
+
+ <div id="panel1" class="panel" tabindex="-1" role="tabpanel" aria-hidden="true" aria-labelledby="tab1">
+ <span>Panel 1</span>
+ <div>Some fields on the panel </div>
+ <div>
+ <p>Enter month and year: <label for="month">Select Month</label>
+ <select id="month">
+ <option value="1">01</option>
+ <option value="2">02</option>
+ <option value="3">03</option>
+ <option value="4">04</option>
+ <option value="5">05</option>
+ <option value="6">06</option>
+ <option value="7">07</option>
+ <option value="8">08</option>
+ <option value="9">09</option>
+ <option value="10">10</option>
+ <option value="11">11</option>
+ <option value="12">12</option>
+ </select>
+ <label for="year">Select Year</label>
+ <select id="year">
+ <option value="2004">2004</option>
+ <option value="2005">2005</option>
+ <option value="2006">2006</option>
+ </select>
+ </p>
+ </div>
+ </div>
+
+ <div id="panel2" class="panel" role="tabpanel" aria-hidden="true" aria-labelledby="tab2">
+ <span>Panel 2</span>
+ <div>Some fields on the panel</div>
+ <div>
+ <input id="internal" name="urlType" value="internal" checked="true" type="radio"><label
for="internal">Internal Portal Bookmark</label>
+ <input id="external" name="urlType" value="external" type="radio"><label for="external">External
URL</label>
+ <br><label for="externalAssoc">URL: </label><input id="externalAssoc" value="" type="text">
+ <hr>
+ </div>
+ </div>
+
+ <div id="panel3" class="panel" role="tabpanel" aria-hidden="true" aria-labelledby="tab3">
+ <span>Panel 3</span>
+ </div>
+
+ <div id="panel4" class="panel" role="tabpanel" aria-hidden="true" aria-labelledby="tab4">
+ <span>Panel 4</span>
+ </div>
+</div>
+</body>
+</html>
diff --git a/test/html/aria-treegrid.html b/test/html/aria-treegrid.html
new file mode 100644
index 0000000..b25e317
--- /dev/null
+++ b/test/html/aria-treegrid.html
@@ -0,0 +1,329 @@
+<html>
+<head>
+ <script type="text/javascript">
+ var sap = {ui:{keycodes:{SPACE:32,
+ ENTER:13,
+ PAGE_UP : 33,
+ PAGE_DOWN : 34,
+ END : 35,
+ HOME : 36,
+ ARROW_LEFT : 37,
+ ARROW_UP : 38,
+ ARROW_RIGHT : 39,
+ ARROW_DOWN : 40,
+ TAB : 9
+ }}};
+ var grids = [];
+ function getGrid(id) {
+ if (!grids[id]) {
+ var grid = {};
+ grid.focusedRow = 1;
+ grid.focusedCol = 0;
+ grid.table = document.getElementById(id);
+ grids[id] = grid;
+ }
+ return grids[id];
+ }
+ function handleFocus(id, evt) {
+ var grid = getGrid(id);
+ if (grid) {
+ if (!grid.focusedCell) {
+ grid.focusedCell = {row:1,col:0};
+ } else {
+ blurCell(grid.focusedCell,grid);
+ }
+ focusCell(grid.focusedCell,grid);
+ grid.table.tabIndex = "-1";
+
+ }
+ }
+ function handleClick(id, evt) {
+ var grid = getGrid(id);
+ if (grid) {
+ var clickedCell = evt.target?evt.target:evt.srcElement;
+ if (clickedCell.tagName=="TD") {
+ row = grid.table.rows[clickedCell.parentNode.rowIndex];
+ toggleItem(row,grid)
+ }
+ }
+ }
+ function toggleItem(row,grid) {
+ var expand;
+ if (row && row.getAttribute("ca")=="to") {
+ expand = grid.table.rows[row.rowIndex+1];
+ while (expand && expand.getAttribute("ca")=="ti") {
+ if (row.getAttribute("aria-expanded")=="false") {
+ expandRow(expand);
+ row.setAttribute("aria-expanded","true");
+ row.getElementsByTagName("SPAN")[0].innerHTML="-";
+ } else {
+ collapseRow(expand);
+ row.setAttribute("aria-expanded","false");
+ row.getElementsByTagName("SPAN")[0].innerHTML="+";
+ }
+ expand = grid.table.rows[expand.rowIndex+1];
+ }
+ }
+ }
+ function expandRow(row) {
+ row.style.display = "";
+ row.setAttribute("aria-hidden","false");
+ }
+ function collapseRow(row) {
+ row.style.display = "none";
+ row.setAttribute("aria-hidden","true");
+ }
+
+ function blurCell(cell,grid) {
+ var td = grid.table.rows[cell.row].cells[cell.col];
+ if (td.getAttribute("editable")=="true") return
+ td.tabIndex = "-1";
+ }
+ function focusCell(cell,grid) {
+ var tr = grid.table.rows[cell.row];
+ var td = tr.cells[cell.col];
+ td.tabIndex = "0";
+ td.focus();
+ }
+ function focusNextRow(grid) {
+ row = grid.table.rows[grid.focusedRow];
+ expand = grid.table.rows[row.rowIndex+1];
+ if (row && row.getAttribute("role")=="row") {
+ row.cells[0].tabIndex = "-1";
+ expand = grid.table.rows[row.rowIndex+1];
+ if (row.getAttribute("aria-expanded")=="false") {
+ while (expand && expand.getAttribute("ca")=="ti") {
+ expand = grid.table.rows[expand.rowIndex+1];
+ }
+ }
+ } else {
+ row.cells[grid.focusedCol].tabIndex = "-1";
+ }
+ if (expand && expand.getAttribute("ca")=="ti") {
+ expand.cells[0].tabIndex ="0";
+ expand.cells[0].focus();
+ grid.focusedRow = expand.rowIndex;
+ } else if (expand) {
+ expand.cells[grid.focusedCol].tabIndex ="0";
+ expand.cells[grid.focusedCol].focus();
+ grid.focusedRow = expand.rowIndex;
+ }
+ }
+
+ function focusPreviousRow(grid) {
+ row = grid.table.rows[grid.focusedRow];
+ expand = grid.table.rows[row.rowIndex-1];
+ if (row) {
+ row.cells[0].tabIndex = "-1";
+ expand = grid.table.rows[row.rowIndex-1];
+ while (expand && expand.style.display=="none") {
+ expand = grid.table.rows[expand.rowIndex-1];
+ }
+ } else {
+ row.cells[grid.focusedCol].tabIndex = "-1";
+ }
+ if (expand && expand.getAttribute("ca")=="ti") {
+ expand.cells[0].tabIndex ="0";
+ expand.cells[0].focus();
+ grid.focusedRow = expand.rowIndex;
+ } else if (expand){
+ expand.cells[grid.focusedCol].tabIndex ="0";
+ expand.cells[grid.focusedCol].focus();
+ grid.focusedRow = expand.rowIndex;
+ }
+ }
+ function focusNextCell(grid) {
+ var row = grid.table.rows[grid.focusedRow];
+ if (row.cells.length>1) {
+ if (grid.focusedCol<row.cells.length-1) {
+ var cell=row.cells[grid.focusedCol];
+ cell.tabIndex="-1";
+ grid.focusedCol++;
+ var cell=row.cells[grid.focusedCol];
+ cell.tabIndex="0";
+ cell.focus();
+ }
+ }
+ }
+
+ function focusPreviousCell(grid) {
+ var row = grid.table.rows[grid.focusedRow];
+ if (row.cells.length>1) {
+ if (grid.focusedCol>0) {
+ var cell=row.cells[grid.focusedCol];
+ cell.tabIndex="-1";
+ grid.focusedCol--;
+ var cell=row.cells[grid.focusedCol];
+ cell.tabIndex="0";
+ cell.focus();
+ }
+ }
+ }
+
+ function handleKeyDown(id, evt) {
+ var grid = getGrid(id);
+ keyCode = evt.keyCode,
+ evtTarget = evt.target ? evt.target : evt.srcElement;
+ if (keyCode == sap.ui.keycodes.ARROW_LEFT) {
+ focusPreviousCell(grid);
+ } else if (keyCode == sap.ui.keycodes.ARROW_RIGHT) {
+ focusNextCell(grid);
+ } else if (keyCode == sap.ui.keycodes.ARROW_UP) {
+ focusPreviousRow(grid);
+ } else if (keyCode == sap.ui.keycodes.ARROW_DOWN) {
+ focusNextRow(grid);
+ } else if (keyCode == sap.ui.keycodes.HOME && evt.ctrlKey) {
+
+ } else if (keyCode == sap.ui.keycodes.END && evt.ctrlKey) {
+
+ } else if (keyCode == sap.ui.keycodes.HOME) {
+
+ } else if (keyCode == sap.ui.keycodes.END) {
+
+ } else if (keyCode == sap.ui.keycodes.SPACE) {
+ row = grid.table.rows[grid.focusedRow];
+ toggleItem(row,grid);
+ }
+ if (keyCode != sap.ui.keycodes.TAB){
+ evt.cancelBubble = true;
+ if (evt.preventDefault)
+ evt.preventDefault();
+ if (evt.stopPropagation) {
+ evt.stopPropagation();
+ } else {
+ evt.cancelBubble = true;
+ evt.returnValue = false;
+ }
+ } else {
+ grid.table.tabIndex = "0";
+ blurCell(grid.focusedCell,grid);
+
+ }
+ }
+ </script>
+
+</head>
+<body>
+ <h3 id="foo">Title</h3>
+ <table aria-labelledby="foo" id="grid-1" border="1" tabindex="0" onfocus="handleFocus('grid-1',event);"
onclick="handleClick('grid-1',event);" onkeydown="handleKeyDown('grid-1',event);" role="treegrid"
style="width:450;">
+ <colgroup><col style="width:150">
+ <col style="width:150">
+ <col style="width:150">
+ </colgroup><thead>
+ <tr role="row">
+ <th id="grid-1-isbn_id">ISBN</th><th id="grid-1-author_id">Author</th><th
id="grid-1-price_id">Price</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ca="to" role="row" aria-expanded="false" aria-level="1">
+ <td headers="grid-1-title_id" colspan="3" aria-labelledby="grid-1-title_id">
+ <span>+</span><strong>A Question of Love</strong></td>
+ </tr>
+ <tr ca="ti" role="row" style="display:none" aria-hidden="true" aria-level="2">
+ <td headers="grid-1-isbn_id" role="gridcell" aria-labelledby="grid-1-isbn_id">
+ 978-3-453-40540-0</td>
+ <td headers="grid-1-author_id" role="gridcell" aria-labelledby="grid-1-author_id">
+ Nora Roberts</td>
+ <td headers="grid-1-price_id" role="gridcell" aria-labelledby="grid-1-price_id">
+ $ 9.99</td>
+ </tr>
+ <tr ca="to" role="row" aria-expanded="false" aria-level="1">
+ <td headers="grid-1-title_id" role="gridcell" colspan="3" aria-labelledby="grid-1-title_id">
+ <span>+</span> <strong>Piece of Peace</strong></td>
+ </tr>
+ <tr ca="ti" role="row" style="display:none" aria-hidden="true" aria-level="2">
+ <td headers="grid-1-isbn_id" role="gridcell" aria-labelledby="grid-1-isbn_id">
+ 978-3-453-477740-0</td>
+ <td headers="grid-1-author_id" role="gridcell" aria-labelledby="grid-1-author_id">
+ Gunther Poison</td>
+ <td headers="grid-1-price_id" role="gridcell" aria-labelledby="grid-1-price_id">
+ $ 13.95</td>
+ </tr>
+ <tr ca="to" role="row" aria-expanded="false" aria-level="1">
+ <td headers="name_id" role="gridcell" colspan="3" aria-labelledby="grid-1-title_id">
+ <span>+</span> <strong>International Law</strong></td>
+ </tr>
+ <tr ca="ti" role="row" style="display:none" aria-hidden="true" aria-level="2">
+ <td headers="grid-1-isbn_id" role="gridcell" aria-labelledby="grid-1-isbn_id">
+ 029-11-131978-07-0</td>
+ <td headers="grid-1-author_id" role="gridcell" aria-labelledby="grid-1-author_id">
+ Daniela Hunter</td>
+ <td headers="grid-1-price_id" role="gridcell" aria-labelledby="grid-1-price_id">
+ $ 11.95</td>
+ </tr>
+ <tr ca="to" role="row" aria-expanded="false" aria-level="1">
+ <td headers="name_id" role="gridcell" colspan="3" aria-labelledby="grid-1-title_id">
+ <span>+</span> <strong>My Name is Benny</strong></td>
+ </tr>
+ <tr ca="ti" role="row" style="display:none" aria-hidden="true" aria-level="2">
+ <td headers="grid-1-isbn_id" role="gridcell" aria-labelledby="grid-1-isbn_id">
+ 007-01-206603-00</td>
+ <td headers="grid-1-author_id" role="gridcell" aria-labelledby="grid-1-author_id">
+ Benjamin Schutz</td>
+ <td headers="grid-1-price_id" role="gridcell" aria-labelledby="grid-1-price_id">
+ $ 12.50</td>
+ </tr>
+ <tr ca="to" role="row" aria-expanded="false" aria-level="1">
+ <td headers="name_id" role="gridcell" colspan="3" aria-labelledby="grid-1-title_id">
+ <span>+</span> <strong>The Charming Butler</strong></td>
+ </tr>
+ <tr ca="ti" role="row" style="display:none" aria-hidden="true" aria-level="2">
+ <td headers="grid-1-isbn_id" role="gridcell" aria-labelledby="grid-1-isbn_id">
+ 007-02-206983-77</td>
+ <td headers="grid-1-author_id" role="gridcell" aria-labelledby="grid-1-author_id">
+ Naomi Jackson</td>
+ <td headers="grid-1-price_id" role="gridcell" aria-labelledby="grid-1-price_id">
+ $ 14.50</td>
+ </tr>
+ <tr ca="to" role="row" aria-expanded="false" aria-level="1">
+ <td headers="name_id" role="gridcell" colspan="3" aria-labelledby="grid-1-title_id">
+ <span>+</span> <strong>Lofts</strong></td>
+ </tr>
+ <tr ca="ti" role="row" style="display:none" aria-hidden="true" aria-level="2">
+ <td headers="grid-1-isbn_id" role="gridcell" aria-labelledby="grid-1-isbn_id">
+ 010-12-656922-70</td>
+ <td headers="grid-1-author_id" role="gridcell" aria-labelledby="grid-1-author_id">
+ Bud Atkinson</td>
+ <td headers="grid-1-price_id" role="gridcell" aria-labelledby="grid-1-price_id">
+ $ 22.99</td>
+ </tr>
+ <tr ca="to" role="row" aria-expanded="false" aria-level="1">
+ <td headers="name_id" role="gridcell" colspan="3" aria-labelledby="grid-1-title_id">
+ <span>+</span> <strong>DOM Objects</strong></td>
+ </tr>
+ <tr ca="ti" role="row" style="display:none" aria-hidden="true" aria-level="2">
+ <td headers="grid-1-isbn_id" role="gridcell" aria-labelledby="grid-1-isbn_id">
+ 234-12-081733-67</td>
+ <td headers="grid-1-author_id" role="gridcell" aria-labelledby="grid-1-author_id">
+ Nurdogan Ghant</td>
+ <td headers="grid-1-price_id" role="gridcell" aria-labelledby="grid-1-price_id">
+ $ 29.10</td>
+ </tr>
+ <tr ca="to" role="row" aria-expanded="false" aria-level="1">
+ <td headers="name_id" role="gridcell" colspan="3" aria-labelledby="grid-1-title_id">
+ <span>+</span> <strong>One Man Show</strong></td>
+ </tr>
+ <tr ca="ti" role="row" style="display:none" aria-hidden="true" aria-level="2">
+ <td headers="grid-1-isbn_id" role="gridcell" aria-labelledby="grid-1-isbn_id">
+ 282-02-1839812-72</td>
+ <td headers="grid-1-author_id" role="gridcell" aria-labelledby="grid-1-author_id">
+ Rose Wood</td>
+ <td headers="grid-1-price_id" role="gridcell" aria-labelledby="grid-1-price_id">
+ $9.30</td>
+ </tr>
+ <tr ca="to" role="row" aria-expanded="false" aria-level="1">
+ <td headers="name_id" role="gridcell" colspan="3" aria-labelledby="grid-1-title_id">
+ <span>+</span> <strong>Sugar Fly</strong></td>
+ </tr>
+ <tr ca="ti" role="row" style="display:none" aria-hidden="true" aria-level="2">
+ <td headers="grid-1-isbn_id" role="gridcell" aria-labelledby="grid-1-isbn_id">
+ 081-01-123093-02</td>
+ <td headers="grid-1-author_id" role="gridcell" aria-labelledby="grid-1-author_id">
+ Naomi Jackson</td>
+ <td headers="grid-1-price_id" role="gridcell" aria-labelledby="grid-1-price_id">
+ $ 20.50</td>
+ </tr>
+ </tbody>
+ </table>
+</body>
+</html>
diff --git a/test/html/back.png b/test/html/back.png
new file mode 100644
index 0000000..de02529
Binary files /dev/null and b/test/html/back.png differ
diff --git a/test/html/bugzilla_top.html b/test/html/bugzilla-top.html
similarity index 100%
rename from test/html/bugzilla_top.html
rename to test/html/bugzilla-top.html
diff --git a/test/html/checked.gif b/test/html/checked.gif
new file mode 100644
index 0000000..9747d7a
Binary files /dev/null and b/test/html/checked.gif differ
diff --git a/test/html/left.png b/test/html/left.png
new file mode 100644
index 0000000..0ab2cb2
Binary files /dev/null and b/test/html/left.png differ
diff --git a/test/html/mixed.gif b/test/html/mixed.gif
new file mode 100644
index 0000000..f246c98
Binary files /dev/null and b/test/html/mixed.gif differ
diff --git a/test/html/right.png b/test/html/right.png
new file mode 100644
index 0000000..738607c
Binary files /dev/null and b/test/html/right.png differ
diff --git a/test/html/slider.png b/test/html/slider.png
new file mode 100644
index 0000000..08706ae
Binary files /dev/null and b/test/html/slider.png differ
diff --git a/test/html/unchecked.gif b/test/html/unchecked.gif
new file mode 100644
index 0000000..9144050
Binary files /dev/null and b/test/html/unchecked.gif differ
diff --git a/test/html/w3-checkbox-label-embedded-menu.html b/test/html/w3-checkbox-label-embedded-menu.html
new file mode 100644
index 0000000..049bb54
--- /dev/null
+++ b/test/html/w3-checkbox-label-embedded-menu.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Checkbox with explicit label containing embedded menu role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="checkbox" id="test">
+ <label for="test">Flash the screen
+ <span role="menu">
+ <span role="menuitem" aria-selected="true">1</span>
+ <span role="menuitem" hidden="">2</span>
+ <span role="menuitem" hidden="">3</span>
+ </span>
+ times.
+ </label>
+
+</body></html>
diff --git a/test/html/w3-checkbox-label-embedded-select.html
b/test/html/w3-checkbox-label-embedded-select.html
new file mode 100644
index 0000000..a060697
--- /dev/null
+++ b/test/html/w3-checkbox-label-embedded-select.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Checkbox with explicit label containing embedded select</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="checkbox" id="test">
+ <label for="test">Flash the screen
+ <select size="1">
+ <option selected="selected">1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ times.
+ </label>
+
+</body></html>
diff --git a/test/html/w3-checkbox-label-embedded-slider.html
b/test/html/w3-checkbox-label-embedded-slider.html
new file mode 100644
index 0000000..06034c0
--- /dev/null
+++ b/test/html/w3-checkbox-label-embedded-slider.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Checkbox with explicit label containing embedded slider role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="checkbox" id="test">
+ <label for="test">foo <input role="slider" type="range" value="5" min="1" max="10" aria-valuenow="5"
aria-valuemin="1" aria-valuemax="10"> baz
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-checkbox-label-embedded-spinbutton.html
b/test/html/w3-checkbox-label-embedded-spinbutton.html
new file mode 100644
index 0000000..b9b7ae6
--- /dev/null
+++ b/test/html/w3-checkbox-label-embedded-spinbutton.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Checkbox with explicit label containing embedded spinbutton role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="checkbox" id="test">
+ <label for="test">foo <input role="spinbutton" type="number" value="5" min="1" max="10"
aria-valuenow="5" aria-valuemin="1" aria-valuemax="10"> baz
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-checkbox-title.html b/test/html/w3-checkbox-title.html
new file mode 100644
index 0000000..4b307ef
--- /dev/null
+++ b/test/html/w3-checkbox-title.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Checkbox with title attribute and no other labeling mechanism</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="checkbox" id="test" title="foo">
+
+</body></html>
diff --git a/test/html/w3-file-label-embedded-combobox.html b/test/html/w3-file-label-embedded-combobox.html
new file mode 100644
index 0000000..b6416b5
--- /dev/null
+++ b/test/html/w3-file-label-embedded-combobox.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>File input with explicit label containing embedded menu role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="file" id="test">
+ <label for="test">Flash the screen
+ <div role="combobox">
+ <div role="textbox"></div>
+ <ul role="listbox">
+ <li role="option" aria-selected="true">1 </li>
+ <li role="option">2 </li>
+ <li role="option">3 </li>
+ </ul>
+ </div>
+ times.
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-file-label-embedded-menu.html b/test/html/w3-file-label-embedded-menu.html
new file mode 100644
index 0000000..46fba49
--- /dev/null
+++ b/test/html/w3-file-label-embedded-menu.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>File input with explicit label containing embedded menu role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="file" id="test">
+ <label for="test">Flash the screen
+ <span role="menu">
+ <span role="menuitem" aria-selected="true">1</span>
+ <span role="menuitem" hidden="">2</span>
+ <span role="menuitem" hidden="">3</span>
+ </span>
+ times.
+ </label>
+
+</body></html>
diff --git a/test/html/w3-file-label-embedded-select.html b/test/html/w3-file-label-embedded-select.html
new file mode 100644
index 0000000..5aaf0a5
--- /dev/null
+++ b/test/html/w3-file-label-embedded-select.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>File input with explicit label containing embedded select</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="file" id="test">
+ <label for="test">Flash the screen
+ <select size="1">
+ <option selected="selected">1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ times.
+ </label>
+
+</body></html>
diff --git a/test/html/w3-file-label-embedded-slider.html b/test/html/w3-file-label-embedded-slider.html
new file mode 100644
index 0000000..3f89bad
--- /dev/null
+++ b/test/html/w3-file-label-embedded-slider.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>File input with explicit label containing embedded slider role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="file" id="test">
+ <label for="test">foo <input role="slider" type="range" value="5" min="1" max="10" aria-valuenow="5"
aria-valuemin="1" aria-valuemax="10"> baz
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-file-label-embedded-spinbutton.html
b/test/html/w3-file-label-embedded-spinbutton.html
new file mode 100644
index 0000000..bba7214
--- /dev/null
+++ b/test/html/w3-file-label-embedded-spinbutton.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>File input with explicit label containing embedded spinbutton role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="file" id="test">
+ <label for="test">foo <input role="spinbutton" type="number" value="5" min="1" max="10"
aria-valuenow="5" aria-valuemin="1" aria-valuemax="10"> baz
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-file-title.html b/test/html/w3-file-title.html
new file mode 100644
index 0000000..837b6ef
--- /dev/null
+++ b/test/html/w3-file-title.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>File input with title attribute and no other labeling mechanism</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="file" id="test" title="foo">
+
+</body></html>
diff --git a/test/html/w3-image-test.png b/test/html/w3-image-test.png
new file mode 100644
index 0000000..2661e29
--- /dev/null
+++ b/test/html/w3-image-test.png
@@ -0,0 +1,2 @@
+
+error: ARIA/1.0/tests/test-files/accessible-name-input/test png 65b1f0c56550: not found in manifest
diff --git a/test/html/w3-image-title.html b/test/html/w3-image-title.html
new file mode 100644
index 0000000..4a9a8f9
--- /dev/null
+++ b/test/html/w3-image-title.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Image input with title attribute and no other labeling mechanism</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="image" src="w3-image-test.png" id="test" title="foo">
+
+</body></html>
diff --git a/test/html/w3-password-label-embedded-combobox.html
b/test/html/w3-password-label-embedded-combobox.html
new file mode 100644
index 0000000..daa7ad4
--- /dev/null
+++ b/test/html/w3-password-label-embedded-combobox.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Password input with explicit label containing embedded menu role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="password" id="test">
+ <label for="test">Flash the screen
+ <div role="combobox">
+ <div role="textbox"></div>
+ <ul role="listbox">
+ <li role="option" aria-selected="true">1</li>
+ <li role="option">2</li>
+ <li role="option">3</li>
+ </ul>
+ </div>
+ times.
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-password-label-embedded-menu.html b/test/html/w3-password-label-embedded-menu.html
new file mode 100644
index 0000000..b596edc
--- /dev/null
+++ b/test/html/w3-password-label-embedded-menu.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Password input with explicit label containing embedded menu role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="password" id="test">
+ <label for="test">Flash the screen
+ <span role="menu">
+ <span role="menuitem" aria-selected="true">1</span>
+ <span role="menuitem" hidden="">2</span>
+ <span role="menuitem" hidden="">3</span>
+ </span>
+ times.
+ </label>
+
+</body></html>
diff --git a/test/html/w3-password-label-embedded-select.html
b/test/html/w3-password-label-embedded-select.html
new file mode 100644
index 0000000..32ec462
--- /dev/null
+++ b/test/html/w3-password-label-embedded-select.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Password input with explicit label containing embedded select</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="password" id="test">
+ <label for="test">Flash the screen
+ <select size="1">
+ <option selected="selected">1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ times.
+ </label>
+
+</body></html>
diff --git a/test/html/w3-password-label-embedded-slider.html
b/test/html/w3-password-label-embedded-slider.html
new file mode 100644
index 0000000..6f8c1f5
--- /dev/null
+++ b/test/html/w3-password-label-embedded-slider.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Password input with explicit label containing embedded slider role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="password" id="test">
+ <label for="test">foo <input role="slider" type="range" value="5" min="1" max="10" aria-valuenow="5"
aria-valuemin="1" aria-valuemax="10"> baz
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-password-label-embedded-spinbutton.html
b/test/html/w3-password-label-embedded-spinbutton.html
new file mode 100644
index 0000000..2a42709
--- /dev/null
+++ b/test/html/w3-password-label-embedded-spinbutton.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Password input with explicit label containing embedded spinbutton role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="password" id="test">
+ <label for="test">foo <input role="spinbutton" type="number" value="5" min="1" max="10"
aria-valuenow="5" aria-valuemin="1" aria-valuemax="10"> baz
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-password-title.html b/test/html/w3-password-title.html
new file mode 100644
index 0000000..2de941e
--- /dev/null
+++ b/test/html/w3-password-title.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Password input with title attribute and no other labeling mechanism</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="password" id="test" title="foo">
+
+</body></html>
diff --git a/test/html/w3-radio-label-embedded-combobox.html b/test/html/w3-radio-label-embedded-combobox.html
new file mode 100644
index 0000000..bf00b92
--- /dev/null
+++ b/test/html/w3-radio-label-embedded-combobox.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Radio button with explicit label containing embedded menu role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="radio" id="test">
+ <label for="test">Flash the screen
+ <div role="combobox">
+ <div role="textbox"></div>
+ <ul role="listbox">
+ <li role="option" aria-selected="true">1</li>
+ <li role="option">2</li>
+ <li role="option">3</li>
+ </ul>
+ </div>
+ times.
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-radio-label-embedded-menu.html b/test/html/w3-radio-label-embedded-menu.html
new file mode 100644
index 0000000..e4a01b8
--- /dev/null
+++ b/test/html/w3-radio-label-embedded-menu.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Radio button with explicit label containing embedded menu role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="radio" id="test">
+ <label for="test">Flash the screen
+ <span role="menu">
+ <span role="menuitem" aria-selected="true">1</span>
+ <span role="menuitem" hidden="">2</span>
+ <span role="menuitem" hidden="">3</span>
+ </span>
+ times.
+ </label>
+
+</body></html>
diff --git a/test/html/w3-radio-label-embedded-select.html b/test/html/w3-radio-label-embedded-select.html
new file mode 100644
index 0000000..79471ae
--- /dev/null
+++ b/test/html/w3-radio-label-embedded-select.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Radio button with explicit label containing embedded select</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="radio" id="test">
+ <label for="test">Flash the screen
+ <select size="1">
+ <option selected="selected">1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ times.
+ </label>
+
+</body></html>
diff --git a/test/html/w3-radio-label-embedded-slider.html b/test/html/w3-radio-label-embedded-slider.html
new file mode 100644
index 0000000..7780e90
--- /dev/null
+++ b/test/html/w3-radio-label-embedded-slider.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Radio button with explicit label containing embedded slider role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="radio" id="test">
+ <label for="test">foo <input role="slider" type="range" value="5" min="1" max="10" aria-valuenow="5"
aria-valuemin="1" aria-valuemax="10"> baz
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-radio-label-embedded-spinbutton.html
b/test/html/w3-radio-label-embedded-spinbutton.html
new file mode 100644
index 0000000..c55b4ba
--- /dev/null
+++ b/test/html/w3-radio-label-embedded-spinbutton.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Radio button with explicit label containing embedded spinbutton role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="radio" id="test">
+ <label for="test">foo <input role="spinbutton" type="number" value="5" min="1" max="10"
aria-valuenow="5" aria-valuemin="1" aria-valuemax="10"> baz
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-radio-title.html b/test/html/w3-radio-title.html
new file mode 100644
index 0000000..98793cb
--- /dev/null
+++ b/test/html/w3-radio-title.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Radio button with title attribute and no other labeling mechanism</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="radio" id="test" title="foo">
+
+</body></html>
diff --git a/test/html/w3-text-label-embedded-combobox.html b/test/html/w3-text-label-embedded-combobox.html
new file mode 100644
index 0000000..3350dac
--- /dev/null
+++ b/test/html/w3-text-label-embedded-combobox.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Text input with explicit label containing embedded menu role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="text" id="test">
+ <label for="test">Flash the screen
+ <div role="combobox">
+ <div role="textbox"></div>
+ <ul role="listbox">
+ <li role="option" aria-selected="true">1</li>
+ <li role="option">2</li>
+ <li role="option">3</li>
+ </ul>
+ </div>
+ times.
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-text-label-embedded-menu.html b/test/html/w3-text-label-embedded-menu.html
new file mode 100644
index 0000000..1798181
--- /dev/null
+++ b/test/html/w3-text-label-embedded-menu.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Text input with explicit label containing embedded menu role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="text" id="test">
+ <label for="test">Flash the screen
+ <span role="menu">
+ <span role="menuitem" aria-selected="true">1</span>
+ <span role="menuitem" hidden="">2</span>
+ <span role="menuitem" hidden="">3</span>
+ </span>
+ times.
+ </label>
+
+</body></html>
diff --git a/test/html/w3-text-label-embedded-select.html b/test/html/w3-text-label-embedded-select.html
new file mode 100644
index 0000000..5c64a93
--- /dev/null
+++ b/test/html/w3-text-label-embedded-select.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Text input with explicit label containing embedded select</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="text" id="test">
+ <label for="test">Flash the screen
+ <select size="1">
+ <option selected="selected">1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ times.
+ </label>
+
+</body></html>
diff --git a/test/html/w3-text-label-embedded-slider.html b/test/html/w3-text-label-embedded-slider.html
new file mode 100644
index 0000000..b79f0c8
--- /dev/null
+++ b/test/html/w3-text-label-embedded-slider.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Text input with explicit label containing embedded slider role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="text" id="test">
+ <label for="test">foo <input role="slider" type="range" value="5" min="1" max="10" aria-valuenow="5"
aria-valuemin="1" aria-valuemax="10"> baz
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-text-label-embedded-spinbutton.html
b/test/html/w3-text-label-embedded-spinbutton.html
new file mode 100644
index 0000000..cea8c74
--- /dev/null
+++ b/test/html/w3-text-label-embedded-spinbutton.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Text input with explicit label containing embedded spinbutton role</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="text" id="test">
+ <label for="test">foo <input role="spinbutton" type="number" value="5" min="1" max="10"
aria-valuenow="5" aria-valuemin="1" aria-valuemax="10"> baz
+ </label>
+
+
+</body></html>
diff --git a/test/html/w3-text-title.html b/test/html/w3-text-title.html
new file mode 100644
index 0000000..d175325
--- /dev/null
+++ b/test/html/w3-text-title.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Text input with title attribute and no other labeling mechanism</title>
+ <style type="text/css"></style></head>
+ <body>
+ <input type="text" id="test" title="foo">
+
+</body></html>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]