class source: Menubar Example 1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:wairole="http://www.w3.org/2005/01/wai-rdf/GUIRoleTaxonomy#"
xmlns:aaa="http://www.w3.org/2005/07/aaa">
<head>
<title>class: Menubar Example 1</title>
<style type="text/css">
/* CSS Document */
dl.menubar,
#content dl.menubar
{
margin: 0px;
padding: .25em;;
border: 1px solid black;
background-color: #CCCCCC;
width: 20em;
}
dl.menubar dt,
#content dl.menubar dt
{
padding: .25em;
display: inline;
}
dl.menubar dt.selected,
#content dl.menubar dt.selected
{
background: black;
color: white;
}
dl.menubar dd,
#content dl.menubar dd
{
margin: 0;
padding: 0;
display: inline;
}
dl.menubar dd dl,
#content dl.menubar dd dl
{
display: none;
}
dl.menubar dd dl.open,
#content dl.menubar dd dl.open {
position: absolute;
display: block;
margin: 0px;
padding: 0px;
border: 1px solid black;
background-color: #CCCCCC;
}
dl.menubar dd dl dt,
#content dl.menubar dd dl dt
{
display: block;
margin: 0;
padding: 0;
padding-top: 2px;
padding-bottom: 2px;
padding-left: 1em;
padding-right: 1em;
width: 8em;
}
dl.menubar dd dl dt.checked,
#content dl.menubar dd dl dt.checked
{
background-image: url(../images/checked.gif);
background-position: -1em center;
background-repeat:no-repeat;
}
dl.menubar dd dl dt.selected,
#content dl.menubar dd dl dt.selected
{
background: black;
color: white;
}
dl.menubar dd dl dt.separator,
#content dl.menubar dd dl dt.separator
{
line-height: 1px;
padding-top: 2px;
border-bottom: thin solid black;
margin-bottom: 2px;
}
</style>
<script type="text/javascript">
//globals.js
/**
*
* The Globale Variables
*/
if (!window.Node) {
var Node = { // If there is no Node object, define one
ELEMENT_NODE: 1, // with the following properties and values.
ATTRIBUTE_NODE: 2, // Note that these are HTML node types only.
TEXT_NODE: 3, // For XML-specific nodes, you need to add
COMMENT_NODE: 8, // other constants here.
DOCUMENT_NODE: 9,
DOCUMENT_FRAGMENT_NODE: 11
}
}
var KEY_PAGEUP = 33;
var KEY_PAGEDOWN = 34;
var KEY_END = 35;
var KEY_HOME = 36;
var KEY_LEFT = 37;
var KEY_UP = 38;
var KEY_RIGHT = 39;
var KEY_DOWN = 40;
var KEY_SPACE = 32;
var KEY_TAB = 9;
var KEY_BACKSPACE = 8;
var KEY_DELETE = 46;
var KEY_ENTER = 13;
var KEY_INSERT = 45;
var KEY_ESCAPE = 27;
var KEY_F1 = 112;
var KEY_F2 = 113;
var KEY_F3 = 114;
var KEY_F4 = 115;
var KEY_F5 = 116;
var KEY_F6 = 117;
var KEY_F7 = 118;
var KEY_F8 = 119;
var KEY_F9 = 120;
var KEY_F10 = 121;
var KEY_M = 77;
var NS_XHTML = "http://www.w3.org/1999/xhtml"
var NS_STATE = "http://www.w3.org/2005/07/aaa";
// **********************************************
// *
// * Commonly used helper functions
// *
// **********************************************
/**
*
* nextSiblingElement
*
* @contructor
*/
function nextSiblingElement( node ) {
var next_node = node.nextSibling;
while( next_node
&& (next_node.nodeType != Node.ELEMENT_NODE) ) {
next_node = next_node.nextSibling;
} // endwhile
return next_node;
}
/**
*
* previousSiblingElement
*
* @param ( node ) node object for which you are looking for the next sibling element node
*
* @return ( node) next sibling or "null"
*/
function previousSiblingElement( node ) {
var next_node = node.previousSibling;
while( next_node
&& (next_node.nodeType != Node.ELEMENT_NODE) ) {
next_node = next_node.previousSibling;
} // endwhile
return next_node;
}
/**
*
* firstChildElement
*
* @param ( node ) node object for which you are looking for the first child element node
*
* @return ( node) next sibling or "null"
*/
function firstChildElement( node ) {
var next_node = node.firstChild;
while( next_node
&& (next_node.nodeType != Node.ELEMENT_NODE) ) {
next_node = next_node.nextSibling;
} // endwhile
return next_node;
}
/**
*
* getTextContentOfNode
*
* @contructor
*/
function getTextContentOfNode( node ) {
var next_node = node.firstChild;
var str = "";
while( next_node ) {
if( (next_node.nodeType == Node.TEXT_NODE ) &&
(next_node.length > 0 )
)
str += next_node.data;
next_node = next_node.nextSibling;
} // endwhile
return str;
}
/**
*
* setTextContentOfNode
*
* @contructor
*/
function setTextContentOfNode( node, text ) {
// Generate a new text node with the text value
var text_node = document.createTextNode(text);
// Remove child nodes to remove text
while (node.firstChild) {
node.removeChild(node.firstChild);
} // while
// Append new text to the container element
node.appendChild( text_node );
}
//widgets_class.js
// JavaScript Document
if (!window.Node) {
var Node = { // If there is no Node object, define one
ELEMENT_NODE: 1, // with the following properties and values.
ATTRIBUTE_NODE: 2, // Note that these are HTML node types only.
TEXT_NODE: 3, // For XML-specific nodes, you need to add
COMMENT_NODE: 8, // other constants here.
DOCUMENT_NODE: 9,
DOCUMENT_FRAGMENT_NODE: 11
}
}
var ARIA_STATE = "aria-";
/**
* Widgets Object is used to initialize a set of controls
* and provide a conveinence fuction to cancel event propagration
* @construtor
*/
function Widgets() {
this.widgets = new Array();
}
/**
* add is member of the Widgets Object
* and used add a widget ot the list of widgets to be intitialized
* as part of the onload event
* The controls array is the list of controls to initialize
* @member Enable
* @return none
*/
Widgets.prototype.add = function(obj) {
this.widgets[this.widgets.length] = obj;
}
/**
* init is member of the Widgets Object
* and is called by the onload event to initialize widgets in the web resource
* The controls array is the list of controls to initialize
* @member Enable
* @return none
*/
Widgets.prototype.init = function() {
for(var i = 0; i < this.widgets.length; i++ )
this.widgets[i].init();
}
//
// convience function for getting the node based on id
function _$( id ) {
return document.getElementById( id );
}
//
// WebBrowser object to abstract accessibility API differences between web standards supporting browsers and Internet Explorer 7.0
//
// The state variable keeps track of current state of checkbox
function WebBrowser() {
}
/**
* Mouse capture
*
* @param ( node ) DOM node object
* @return nothing
*/
if ( document.addEventListener ) {
// If a web standards based browser implement this function
WebBrowser.prototype.setMouseCapture = function( node, clickHandler, downHandler, moveHandler, upHandler ) {
if( clickHandler )
document.addEventListener( "click", clickHandler, true );
if( downHandler )
document.addEventListener( "mousedown", downHandler, true );
if( moveHandler )
document.addEventListener( "mousemove", moveHandler, true );
if( upHandler)
document.addEventListener( "mouseup", upHandler, true );
}
WebBrowser.prototype.releaseMouseCapture = function( node, clickHandler, downHandler, moveHandler, upHandler ) {
if( upHandler)
document.removeEventListener( "mouseup", upHandler, true );
if( moveHandler )
document.removeEventListener( "mousemove", moveHandler, true );
if( downHandler )
document.removeEventListener( "mousedown", downHandler, true );
if( clickHandler )
document.removeEventListener( "click", clickHandler, true );
}
} else {
// If a Microsoft IE based browser implement this function
WebBrowser.prototype.setMouseCapture = function( node, clickHandler, downHandler, moveHandler, upHandler ) {
node.setCapture();
if( clickHandler)
node.attachEvent( "onclick", clickHandler );
if( downHandler)
node.attachEvent( "onmousedown", downHandler );
if( moveHandler )
node.attachEvent( "onmousemove", moveHandler );
if( upHandler )
node.attachEvent( "onmouseup", upHandler );
} // endif
WebBrowser.prototype.releaseMouseCapture = function( node, clickHandler, downHandler, moveHandler, upHandler ) {
if( upHandler )
node.detachEvent( "onmouseup", upHandler );
if( moveHandler )
node.detachEvent( "onmousemove", moveHandler );
if( downHandler)
node.detachEvent( "onmousedown", downHandler );
if( clickHandler)
node.detachEvent( "onclick", clickHandler );
node.releaseCapture();
} // endif
}
/**
* OnClick Event Simulator
*
* @param ( node ) DOM node object
* @return nothing
*/
if( document.createEvent ) {
// If a web standards based browser implement this function
WebBrowser.prototype.simulateOnClickEvent = function( node ) {
// W3C DOM Events way to trigger a "click" event
var e = document.createEvent('MouseEvents');
e.initEvent( 'click', true, true );
node.dispatchEvent( e );
}
} else {
// If a Microsoft IE based browser implement this function
WebBrowser.prototype.simulateOnClickEvent = function( node ) {
var e = document.createEventObject();
node.fireEvent( "onclick", e );
} // endif
}
//
// keyCode is a function to get the keycode from a keypress event
//
// @param ( event object) event is an event object
//
// @return ( keycode )
WebBrowser.prototype.keyCode = function( event ) {
var e = event || window.event;
return e.keyCode;
}
if (typeof document.documentElement.setAttributeNS != 'undefined') {
WebBrowser.prototype.stopPropagation = function( event ) {
event.stopPropagation();
event.preventDefault();
return false;
}
WebBrowser.prototype.target = function( event ) {
return event.target;
}
WebBrowser.prototype.charCode = function(event) {
return event.charCode;
}
WebBrowser.prototype.calculateOffsetLeft = function( node ) {
return node.offsetLeft;
}
WebBrowser.prototype.calculateOffsetTop = function( node ) {
return node.offsetTop;
}
WebBrowser.prototype.pageX = function( e ) {
return e.pageX;
}
WebBrowser.prototype.pageY = function( e ) {
return e.pageY;
}
WebBrowser.prototype.setNodePosition = function(node,left,top) {
node.style.left = left+"px";
node.style.top = top+"px";
}
} else {
WebBrowser.prototype.stopPropagation = function( event ) {
window.event.cancelBubble = true;
window.event.returnValue = false;
return false;
}
WebBrowser.prototype.charCode = function(event) {
return window.browser.keyCode( event );
}
WebBrowser.prototype.target = function( event ) {
return window.event.srcElement;
}
WebBrowser.prototype.calculateOffsetLeft = function(node) {
var offset = 0;
while( node ) {
offset += node.offsetLeft;
node = node.offsetParent;
}
return offset;
}
WebBrowser.prototype.calculateOffsetTop = function(node) {
var offset = 0;
while( node ) {
offset = offset + node.offsetTop;
node = node.offsetParent;
}
return offset;
}
WebBrowser.prototype.pageX = function( e ) {
return e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
}
WebBrowser.prototype.pageY = function( e ) {
return e.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
}
WebBrowser.prototype.setNodePosition = function(node,left,top) {
var offsetx = 0;
var offsety = 0;
var nnode = node.offsetParent
while( nnode ) {
offsetx = offsetx + nnode.offsetLeft;
offsety = offsety + nnode.offsetTop;
nnode = nnode.offsetParent;
}
node.style.left = left-offsetx+"px";
node.style.top = top-offsety+"px";
}
};
if (document.addEventListener) {
// Functions for W3C Standards compliant implementation of adding event handlers
WebBrowser.prototype.addEvent = function(elmTarget, sEventName, fCallback) {
elmTarget.addEventListener(sEventName, fCallback, false);
returnValue = true;
};
WebBrowser.prototype.removeEvent = function(elmTarget, sEventName, fCallback) {
elmTarget.removeEventListener(sEventName, fCallback, false);
returnValue = true;
};
WebBrowser.prototype.addChangeEvent = function(elmTarget, fCallback) {
elmTarget.addEventListener("DOMAttrModified", fCallback, false);
returnValue = true;
};
} else {
if(document.attachEvent) {
// IE Specific Event handler functions
WebBrowser.prototype.addEvent = function(elmTarget, sEventName, fCallback) {
returnValue = elmTarget.attachEvent('on' + sEventName, fCallback);
};
WebBrowser.prototype.removeEvent = function(elmTarget, sEventName, fCallback) {
returnValue = elmTarget.detachEvent('on' + sEventName, fCallback);
};
WebBrowser.prototype.addChangeEvent = function(elmTarget, fCallback) {
returnValue = elmTarget.attachEvent("onpropertychange", fCallback);
};
} else {
// For browsers that do not support W3C or IE event functions
WebBrowser.prototype.addEvent = function(elmTarget, sEventName, fCallback) {
return false;
};
WebBrowser.prototype.removeEvent = function(elmTarget, sEventName, fCallback) {
return false;
};
WebBrowser.prototype.addChangeEvent = function(elmTarget, fCallback) {
return false;
};
}
}
//
// ARIA functions to absract the setting and reading of ARIA features
// This is important since the ARIA specification is not completely defined
// This makes it easier to make syntactic changes to examples
//
function ARIA() {
}
ARIA.prototype.setAriaState = function(elmTarget, sStateName, sStateValue) {
elmTarget.setAttribute(ARIA_STATE + sStateName, sStateValue);
}
ARIA.prototype.setRole = function(elmTarget, sStateValue) {
elmTarget.setAttribute("role", sStateValue);
}
ARIA.prototype.getAriaState = function(elmTarget, sStateName) {
return elmTarget.getAttribute(ARIA_STATE + sStateName);
}
ARIA.prototype.removeAriaState = function(elmTarget, sStateName) {
return elmTarget.removeAttribute(ARIA_STATE + sStateName);
}
ARIA.prototype.hasAriaState = function(elmTarget, sStateName) {
return elmTarget.hasAttribute(ARIA_STATE + sStateName);
}
ARIA.prototype.setRolesAndStates = function(elmAccessible)
{
var STATE_MACHINE_BEGIN = 0;
var STATE_MACHINE_IN_ACCESSIBLE = 1;
var STATE_MACHINE_ROLE_IS_SET = 2;
var sClass = elmAccessible.className;
var arClassNames = sClass.split(' ');
var machineState = STATE_MACHINE_BEGIN;
var role = "";
for (j = 0; j < arClassNames.length; j++) {
// Delete spaces in CNAMEs
var sClass = arClassNames[j].replace(/ /g, '');
// alert(sClass + " " + machineState);
// Test to see if there are any CNAMEs to process, if not exit
if (!sClass) { continue; }
// Look for CNAMEs assocaited with ARIA markup
if ( sClass == 'axs' ) {
/* found "axs" accessible keyword, rest of class will be treated as ARIA roles and states */
machineState = STATE_MACHINE_IN_ACCESSIBLE;
} else if (machineState == STATE_MACHINE_IN_ACCESSIBLE) {
// alert(elmAccessible.id + " " + sClass);
/* found role, set it and move on */
if( sClass != 'norole')
this.setRole(elmAccessible, sClass);
machineState = STATE_MACHINE_ROLE_IS_SET;
role = sClass;
} else if (machineState == STATE_MACHINE_ROLE_IS_SET) {
/* found state, set it and look for more */
if (sClass.indexOf('-') != -1) {
/* state has specific value, parse it out and set it */
var arValue = sClass.split(/-/);
// arValue[0] is state name, arValue[1] is value
//
// test for tabindex value
if( arValue[0] != "tabindex" )
//
// If not tabindex set the aria property and value
this.setAriaState(elmAccessible, arValue[0], arValue[1]);
else {
//
// If tabindex use Microsoft IE property to set tabindex value
if( arValue[1] != "" ) {
// alert("Tabindex=" + arvalue[1]);
elmAccessible.tabIndex = arValue[1];
} else {
// if tabindex value is undefined assume it is a negative number and set tabindex=-1
// alert("Tabindex=-1");
elmAccessible.tabIndex = -1;
}
}
} else {
/* state is simply a name, value is null - make it a string to match other values as strings*/
this.setAriaState(elmAccessible, sClass, "");
}
}
}
};
initApp = function(elmRoot) {
if (document.isInitialized) {
return; // Avoid second initialization -- we inited early because of DOMContentLoaded
}
document.isInitialized = true;
// If elmRoot is undefined start with the BODY element
if ((!elmRoot) || (!elmRoot.getElementsByTagName)) {
elmRoot = document.body;
}
// Check elmRoot node for information in the CLASS attribute to convert to ARIA markup
if (/axs /.test(elmRoot.className)) {
aria.setRolesAndStates(elmRoot); // First do root element
}
//
// Check for W3C Standards compliant implementation of XPATH evaluation
if (document.evaluate) {
// Get ARIA Roles and States
var snapAccessibleElements = document.evaluate(".//*[contains(@class, 'axs ')]", elmRoot, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = snapAccessibleElements.snapshotLength - 1; i >= 0; i--) {
aria.setRolesAndStates(snapAccessibleElements.snapshotItem(i), "wairole:");
}
//
// Otherwise use Micrsoft IE technique for identifying nodes
} else {
var axsElements = new Array();
var axsElementCount = 0;
var arElements = (typeof elmRoot.all != 'undefined') ? elmRoot.all : elmRoot.getElementsByTagName('*');
var iElementCount = arElements.length;
//
// Find elements with ARIA markup and save their IDs
for (var i = 0; i < iElementCount; i++) {
if (/axs /.test(arElements[i].className)) {
aria.setRolesAndStates(arElements[i]);
} // endif
} // endfor
} // endif
// Initialize widgets
widgets.init();
};
// Initialize global variables used to initial widgets and provide browser independence for handling events and lack of namespace support in IE DOM functions
widgets_flag = true;
var widgets = new Widgets();
var browser = new WebBrowser();
var aria = new ARIA();
//menubar1_class.js
// JavaScript Document
var MENUITEM_NONE = 0;
var MENUITEM_ITEM = 1;
var MENUITEM_RADIO = 2;
var MENUITEM_CHECKBOX = 3;
var MENUITEM_SEPARATOR = 4;
/**
* NODE_LAST_FOCUS keeps track of which form element in the tab panel had last focus
*/
var NODE_LAST_FOCUS = null;
/**
*
* The TabPanel object is used to maintain information about a Tab Panel widget
* including the collection of tab objects
*
* @contructor
*/
function MenuBar( id ) {
this.id = id;
this.current_menubar_node = null;
this.current_menu_node = null;
this.current_menuitem_node = null;
this.current_menuitems;
this.pulldown_flag = false;
}
/**
* init is a subclass of MenuBar and is used to initialize the event handlers and
* tabs in a menu bar.
*
* @member MenuBar
* @return nothing
*/
MenuBar.prototype.init = function() {
this.node = document.getElementById(this.id);
var obj = this;
browser.addEvent(this.node, "focus", function(event) {handleMenuBarFocusEvent(event, obj); }, false);
browser.addEvent(this.node, "click", function(event) {handleMenuBarClickEvent(event, obj); }, false);
browser.addEvent(this.node, "mouseover", function(event) {handleMenuBarMouseOverEvent(event, obj); }, false);
browser.addEvent(this.node, "keydown", function(event) {handleMenuBarKeyDownEvent(event, obj); }, false);
}
/**
* setMenuBarFocus
* Give the menu focus
*
* @param ( menubar ) MenuBar object
* @return none
*/
function setMenuBarFocus( menubar ) {
menubar.node.focus();
}
/**
* getFirstMenuItem
* This function gets the next menu item in the current menu
*
* @param ( menubar ) MenuBar object
* @return node of new menu item
*/
function getFirstMenuItem( menubar ) {
var done = false;
var first_menu_item = menubar.node.firstChild;
do {
if( ( first_menu_item.nodeType == Node.ELEMENT_NODE ) &&
( first_menu_item.getAttribute("role") == "menuitem" ) ) {
done = true;
} else {
first_menu_item = nextSiblingElement( first_menu_item );
}
} while( first_menu_item && !done);
return first_menu_item;
}
/**
* getLastMenuItem
* This function gets the next menu item in the current menu
*
* @param ( menubar ) MenuBar object
* @return node of new menu item
*/
function getLastMenuItem( menubar ) {
var done = false;
var last_menu_item = menubar.node.lastChild;
do {
if( ( last_menu_item.nodeType == Node.ELEMENT_NODE ) &&
( last_menu_item.getAttribute("role") == "menuitem" ) ) {
done = true;
} else {
last_menu_item = previousSiblingElement( last_menu_item );
}
} while( last_menu_item && !done);
return last_menu_item;
}
/**
* getNextMenuItem
* This function gets the next menu item in the current menubar
*
* @param ( menubar ) MenuBar object
* @return node of new menu item
*/
function getNextMenuItem( menubar ) {
var done = false;
var next_menu_item;
if( menubar.current_menubar_node == null )
next_menu_item = menubar.node.firstChild;
else
next_menu_item = menubar.current_menubar_node.nextSibling;
do {
if( ( next_menu_item.nodeType == Node.ELEMENT_NODE ) &&
( next_menu_item.getAttribute("role") == "menuitem" ) ) {
done = true;
} else {
next_menu_item = nextSiblingElement( next_menu_item );
}
} while( next_menu_item && !done);
if( next_menu_item == null )
next_menu_item = getFirstMenuItem( menubar );
return next_menu_item;
}
/**
* getPreviousMenuItem
* This function gets the previous menu item in the current menu
*
* @param ( menubar ) MenuBar object
*
* @return node of new menu item
*/
function getPreviousMenuItem( menubar ) {
var done = false;
var previous_menu_item;
if( menubar.current_menubar_node == null )
previous_menu_item = menubar.node.lastChild;
else
previous_menu_item = menubar.current_menubar_node.previousSibling;
do {
if( ( previous_menu_item.nodeType == Node.ELEMENT_NODE ) &&
( previous_menu_item.getAttribute("role") == "menuitem" ) ) {
done = true;
} else {
previous_menu_item = previousSiblingElement( previous_menu_item );
}
} while( previous_menu_item && !done);
if( previous_menu_item == null )
previous_menu_item = getLastMenuItem( menubar );
return previous_menu_item;
}
/**
* openPreviousMenuItem
*
* @param ( menubar ) MenuBar object
* @param ( menuitem ) MenuItem object
*
* @return node of new menu item
*/
function openPullDownMenu( menubar, menuitem ) {
var new_menu = nextSiblingElement(menuitem);
while ( new_menu && new_menu.getAttribute("role") != "menu" ) {
new_menu = firstChildElement(new_menu);
}
if( new_menu ) {
new_menu.className = "open";
browser.setNodePosition( new_menu, browser.calculateOffsetLeft( menuitem), (browser.calculateOffsetTop( menuitem) + menuitem.offsetHeight ));
browser.addEvent(new_menu, "mouseover", function(event) {handleMenuMouseOverEvent(event, menubar); }, false);
}
menubar.current_menu_node = new_menu;
menubar.current_menuitems = new Array();
var item_node = firstChildElement( menubar.current_menu_node );
do {
if( item_node.nodeType == Node.ELEMENT_NODE ) {
var mi_node = null;
var mi_type = MENUITEM_NONE;
var mi_checked = item_node.getAttribute("aria-checked")
var mi_disabled = item_node.getAttribute("aria-disabled")
var mi_haspopup = item_node.getAttribute("aria-haspopup");
if( item_node.getAttribute("role") == "menuitem" ) {
mi_node = item_node;
mi_type = MENUITEM_ITEM;
} // endif
if( item_node.getAttribute("role") == "menuitemradio" ) {
mi_node = item_node;
mi_type = MENUITEM_RADIO;
} // endif
if( item_node.getAttribute("role") == "menuitemcheckbox" ) {
mi_node = item_node;
mi_type = MENUITEM_CHECKBOX;
} // endif
if( item_node.getAttribute("role") == "separator" ) {
mi_node = item_node;
mi_type = MENUITEM_SEPARATOR;
} // endif
if( mi_node ) {
var menuitem = new MenuItem( mi_node.id, mi_type, mi_checked, mi_disabled, mi_haspopup );
menubar.current_menuitems[menubar.current_menuitems.length] = menuitem;
}
} // endif
item_node = item_node.nextSibling;
} while( item_node );
return new_menu;
}
/**
* closePullDownMenuItem
*
* @param ( menubar ) MenuBar object
* @param ( menuitem ) MenuItem object
*
* @return node of new menu item
*/
function closePullDownMenu( menubar, menuitem ) {
var old_menu = nextSiblingElement(menuitem);
while ( old_menu && old_menu.getAttribute("role") != "menu" ) {
old_menu = firstChildElement(old_menu);
}
if( old_menu ) {
old_menu.className = "";
browser.removeEvent(old_menu, "mouseover", function(event) {handleMenuMouseOverEvent(event, menubar); }, false);
}
return old_menu;
}
/**
* menuBarUpdateMenuBar
* Supports moving to the next menu item
*
* @param ( menubar ) MenuBar object
* @return nothing
*/
function menuBarUpdateMenuBar( menubar, new_node ) {
var last_node = menubar.current_menubar_node;
// Close old menu item if open
if( last_node != new_node ) {
// change styling on old menu item
if( last_node != null ) {
last_node.className = "";
// Check to see if there is a pull down menu
if( menubar.pulldown_flag &&
last_node.getAttribute("aria-haspopup") == "true" ) {
closePullDownMenu( menubar, last_node );
}
}
// Update styling
if( new_node != null ) {
new_node.className = "selected";
menubar.current_menubar_node = new_node;
// Check to see if there is a pull down menu
if( menubar.pulldown_flag &&
new_node.getAttribute("aria-haspopup") == "true" ) {
menubar.current_menu_node = openPullDownMenu( menubar, new_node );
}
} // endif
} // endif
}
/**
* menuBarUpdateMenu
* Supports updating the styling of the current menu that is open
*
* @param ( menubar ) MenuBar object
* @return nothing
*/
function menuBarUpdateMenu( menubar, new_menuitem_node ) {
// see if any other nodes ae currently selected and restore their default styling
if( menubar.current_menuitem_node &&
( menubar.current_menuitem_node.getAttribute("role") != "separator" ) )
if( menubar.current_menuitem_node.getAttribute("aria-checked") == "true" )
menubar.current_menuitem_node.className = "checked ";
else
menubar.current_menuitem_node.className = "";
menubar.current_menuitem_node = new_menuitem_node;
// Set the new node to a selected style
if( menubar.current_menuitem_node &&
menubar.current_menuitem_node.getAttribute("role") != "separator" )
if( menubar.current_menuitem_node.getAttribute("aria-checked") == "true" )
menubar.current_menuitem_node.className = "checked selected";
else
menubar.current_menuitem_node.className = "selected";
return menubar.current_menuitem_node;
}
/**
* menuBarKeyLeft
* Supports moving to the next menu item
*
* @param ( menubar ) MenuBar object
* @return nothing
*/
function menuBarKeyLeftArrow( menubar ) {
var new_node = getPreviousMenuItem( menubar );
menuBarUpdateMenuBar( menubar, new_node );
if( new_node.getAttribute("aria-haspopup") == "true") {
menuBarKeyDownArrow( menubar );
} else {
new_node.focus();
} // endif
}
/**
* menuBarKeyRight
* Supports moving to the previous menu item
*
* @param ( menubar) MenuBar object
* @return nothing
*/
function menuBarKeyRightArrow( menubar ) {
var new_node = getNextMenuItem( menubar );
menuBarUpdateMenuBar( menubar, new_node );
if( new_node.getAttribute("aria-haspopup") == "true") {
menuBarKeyDownArrow( menubar );
} else {
new_node.focus();
} // endif
}
/**
* MenuItem constructor for storing data on a menuitem node
*
* @param ( id ) id of node of menuitem
* @param ( type ) integer indicting the type of menuitem
* @param ( checked ) boolean flag indicating if the menuitem is checked
* @param ( disabled ) boolean flag indicating if the menuitem is disabled
* @param ( haspopup ) boolean flag indicating if the menuitem has a popup menu
* @return nothing
*/
function MenuItem( id, type, checked, disabled, haspopup ) {
this.id = id;
this.type = type;
this.checked = checked;
this.disabled = disabled;
this.haspopup = haspopup;
}
/**
* getMenuItems
* Get an array of the current menu items
*
* @param ( menu) menu object
* @return nothing
*/
function getMenuItems( menu_node ) {
return menuitems;
}
/**
* getMenuItemItemIndex
*
*
* @param ( menu ) menu object
* @return -1 If menuitem is not in array
* >= 0 The index position in the array
*/
function getMenuItemIndex( menubar ) {
var index = -1;
var i = 0;
var done = false;
// Test to see if current menu item selected
if( menubar.current_menuitem_node ) {
while ( ( i < menubar.current_menuitems.length ) && !done ) {
if( menubar.current_menuitems[i].id == menubar.current_menuitem_node.id ) {
done = true;
index = i;
}
i++;
} // end while
} // endif
return index;
}
/**
* menuBarKeyUp
* Supports moving to the previous menu item
*
* @param ( menubar) MenuBar object
* @return nothing
*/
function menuBarKeyUpArrow( menubar ) {
// see if menu has a popup
if( !menubar.current_menu_node &&
menubar.current_menubar_node.getAttribute("aria-haspopup") == "true" ) {
menubar.current_menu_node = openPullDownMenu( menubar, menubar.current_menubar_node );
menubar.pulldown_flag = true;
} // endif
if( menubar.current_menu_node ) {
var index = getMenuItemIndex( menubar );
index--;
while( (index >= 0) && (menubar.current_menuitems[index].type == MENUITEM_SEPARATOR ) ){
index--;
}
if( (index < 0 ) || ( index >= menubar.current_menuitems.length ) )
index = menubar.current_menuitems.length - 1;
var new_node = menuBarUpdateMenu(menubar, document.getElementById(menubar.current_menuitems[index].id) );
new_node.focus();
} // endif
}
/**
* menuBarKeyUp
* Supports moving to the previous menu item
*
* @param ( menubar) MenuBar object
* @return nothing
*/
function menuBarKeyDownArrow( menubar ) {
// see if menu has a popup
if( !menubar.current_menu_node &&
menubar.current_menubar_node.getAttribute("aria-haspopup") == "true" ) {
menubar.current_menu_node = openPullDownMenu( menubar, menubar.current_menubar_node );
menubar.pulldown_flag = true;
} // endif
if( menubar.current_menu_node ) {
var index = getMenuItemIndex( menubar );
index++;
while( (index < menubar.current_menuitems.length) && (menubar.current_menuitems[index].type == MENUITEM_SEPARATOR ) ){
index++;
}
if( (index < 0 ) || ( index >= menubar.current_menuitems.length ) )
index = 0;
var new_node = menuBarUpdateMenu(menubar, document.getElementById(menubar.current_menuitems[index].id) );
new_node.focus();
} // endif
}
/**
* menuBarOnClick
* Supports moving to the previous menu item
*
* @param ( menubar) MenuBar object
* @return nothing
*/
function menuBarOnClick( menubar ) {
if( menubar.current_menuitem_node ) {
browser.simulateOnClickEvent( menubar.current_menuitem_node );
} // endif
}
/**
* menuBarClosePulldown
* Close pull down menu if it is open
*
* @param ( menubar) MenuBar object
* @return nothing
*/
function menuBarClosePullDown( menubar ) {
if( menubar.current_menubar_node ) {
// Check to see if there is a pull down menu
if( menubar.current_menubar_node.getAttribute("aria-haspopup") == "true" ) {
closePullDownMenu( menubar, menubar.current_menubar_node );
} // endif
menubar.current_menubar_node.focus();
} // endif
}
/**
* menuBarUpdateRadioMenuItems
*
* @param ( menubar) MenuBar object
* @return nothing
*/
function menuBarUpdateRadioMenuItems( menubar ) {
var node;
var i = getMenuItemIndex( menubar );
var j;
//
// uncheck any other radiomenuitems before current menuitem
j = i-1;
while( (j >= 0) &&
( menubar.current_menuitems[j].type == MENUITEM_RADIO) ) {
node = document.getElementById( menubar.current_menuitems[j].id );
node.setAttribute("aria-checked", "false" );
node.className = "";
j--;
} // endwhile
menubar.current_menuitem_node.setAttribute("aria-checked", "true" );
menubar.current_menuitem_node.className = "checked";
//
// uncheck any other radiomenuitems before current menuitem
j = i + 1;
while( (j < menubar.current_menuitems.length) &&
(menubar.current_menuitems[j].type == MENUITEM_RADIO) ) {
node = document.getElementById( menubar.current_menuitems[j].id );
node.setAttribute("aria-checked", "false" );
node.className = "";
j++;
} // endwhile
}
/**
* menuBarUpdateCheckboxMenuItems
*
* @param ( menubar) MenuBar object
* @return nothing
*/
function menuBarUpdateCheckboxMenuItems( menubar, checked ) {
if( checked ) {
menubar.current_menuitem_node.setAttribute("aria-checked", "true" );
menubar.current_menuitem_node.className = "checked";
} else {
menubar.current_menuitem_node.setAttribute("aria-checked", "false" );
menubar.current_menuitem_node.className = "";
} // endif
}
/**
* menuBarClose
*
* @param ( menubar) MenuBar object
* @return nothing
*/
function menuBarClose( menubar ) {
menuBarClosePullDown( menubar );
// reset styling of current menubar item
if( menubar.current_menubar_node )
menubar.current_menubar_node.className = "";
menubar.current_menubar_node = null;
menubar.current_menu_node = null;
menubar.current_menubar_node = null;
menubar.pulldown_flag = false;
}
/**
* handleMenuBarKeyPressEvent
* handleMenuBatKetDownEvent Keyboard commands for the Menubar
*
* @param ( event object ) event
* @param ( MenuBar object) menubar is the MenuBar object associated with the event
* @return boolean false if the event was used by MenuBar, otherwise true
*/
function handleMenuBarKeyDownEvent(event, menubar) {
var e = event || window.event;
// If any modifier keys are pressed do not process this event
if( e.altKey || e.ctrlKey || e.shiftKey )
return true;
switch( browser.keyCode( e ) ) {
case KEY_LEFT:
menuBarKeyLeftArrow( menubar );
menubar.my_key_flag = false;
return browser.stopPropagation( e );
break;
case KEY_RIGHT:
menuBarKeyRightArrow( menubar );
menubar.my_key_flag = false;
return browser.stopPropagation( e );
break;
case KEY_UP:
menuBarKeyUpArrow( menubar );
menubar.my_key_flag = false;
return browser.stopPropagation( e );
break;
case KEY_DOWN:
menuBarKeyDownArrow( menubar );
menubar.my_key_flag = false;
return browser.stopPropagation( e );
break;
case KEY_ESCAPE:
menuBarClosePullDown( menubar );
menubar.pulldown_flag = false;
menubar.current_menu_node = null;
menubar.current_menu_node = null;
menubar.my_key_flag = false;
return browser.stopPropagation( e );
break;
case KEY_ENTER:
menuBarOnClick( menubar );
menuBarUpdateMenuBar( menubar, null );
menubar.my_key_flag = false;
return browser.stopPropagation( e );
break;
case KEY_TAB:
menuBarClose( menubar );
break;
} // endif
return true;
}
/**
* handleMenuBarClickEvent
*
* @param ( event object ) event
* @param ( MenuBar object) menubar is the MenuBar object associated with the event
* @return boolean false if the event was used by MenuBar, otherwise true
*/
handleMenuBarClickEvent = function(event, menubar) {
var e = event || window.event;
if( browser.target( e ) == menubar.current_menubar_node ) {
if( menubar.current_menubar_node.getAttribute("aria-haspopup") == "true" ) {
menubar.current_menu_node = openPullDownMenu( menubar, menubar.current_menubar_node );
menubar.pulldown_flag = true;
} //endif
} // endif
return true;
}
/**
* handleMenuBarMouseOver
*
* @param ( event object ) event
* @param ( MenuBar object) menubar is the MenuBar object associated with the event
* @return boolean false if the event was used by MenuBar, otherwise true
*/
handleMenuBarMouseOverEvent = function(event, menubar) {
var e = event || window.event;
var n = menubar.node.firstChild;
while( n ) {
if( (n.nodeType == Node.ELEMENT_NODE) &&
(n.getAttribute("role") == "menuitem" ) ) {
if( n == browser.target( e ) ) {
menuBarUpdateMenuBar( menubar, n );
break;
} // endif
} // endif
n = n.nextSibling;
} // endwhile
return true;
}
/**
* handleMenuMouseOver
*
* @param ( event object ) event
* @param ( MenuBar object) menubar is the MenuBar object associated with the event
* @return boolean false if the event was used by MenuBar, otherwise true
*/
handleMenuMouseOverEvent = function(event, menubar) {
var e = event || window.event;
if( menubar.current_menuitems ) {
for(var index = 0; index < menubar.current_menuitems.length; index++ ) {
var n = document.getElementById(menubar.current_menuitems[index].id );
if( browser.target( e ) == n ) {
menuBarUpdateMenu( menubar, n );
break;
} // endif
} // endfor
} // endfor
return true;
}
/**
* handleMenuBarFocusEvent
*
* @param ( event object ) event
* @param ( MenuBar object) menubar is the MenuBar object associated with the event
* @return boolean false if the event was used by MenuBar, otherwise true
*/
handleMenuBarFocusEvent = function(event, menubar) {
var e = event || window.event;
if( browser.target( e ) == menubar.node ) {
var new_node = getNextMenuItem( menubar );
menuBarUpdateMenuBar( menubar, new_node );
} // endif
return true;
}
/**
* handleMenuBarBlurEvent
*
* @param ( event object ) event
* @param ( MenuBar object) menubar is the MenuBar object associated with the event
* @return boolean false if the event was used by MenuBar, otherwise true
*/
handleMenuBarBlurEvent = function(event, menubar) {
var e = event | window.event;
return true;
}
/**
* StyledText Object
*
* @param ( id ) id of text to style
* @return none
*/
function StyledText( id, menu_ids, menubar ) {
this.id = id;
this.menu_item_ids = menu_ids;
this.menubar = menubar;
}
/**
* init is a subclass of StyledText
* tabs in a menu bar.
*
* @member StyleText
* @return nothing
*/
StyledText.prototype.init = function() {
this.node = document.getElementById(this.id);
this.fontSize = 2;
this.fontSizes = ['x-small', 'small', 'medium', 'large', 'x-large'];
var obj = this;
browser.addEvent(this.node, "keydown", function(event) {handleStyledTextKeyDownEvent(event, obj); }, false);
}
/**
* handleStyledTextKeyPressEvent
* handleStyledTextKetDownEvent Keyboard commands for the Menubar
*
* @param ( event object ) event
* @param ( StyledText object) stext us a StykedText object associated with the event
* @return boolean false if the event was used by MenuBar, otherwise true
*/
function handleStyledTextKeyDownEvent(event, stext ) {
var e = event || window.event;
// If any modifier keys are pressed do not process this event
if( e.ctrlKey || e.shiftKey )
return true;
alert( browser.keyCode( e ) );
switch( browser.keyCode( e ) ) {
case KEY_M:
if( e.altKey ) {
setMenuBarFocus(stext.menubar);
return browser.stopPropagation( e );
}
break;
} // endif
return true;
}
/**
* handleStyledTextSetFont
* handlers changing
*
* @param ( MenuBar object) styled text to hav its font changed
* @param ( StyledText object) styled text to hav its font changed
* @return nothing
*/
function handleStyledTextSetFontFamily( menubar, stext, family ) {
stext.node.style.fontFamily = family;
menuBarUpdateRadioMenuItems( menubar );
menuBarClose( menubar );
stext.node.focus();
}
/**
* handleStyledTextSetJustification
* handlers changing
*
* @param ( MenuBar object) styled text to hav its font changed
* @param ( StyledText object) styled text to hav its font changed
* @return nothing
*/
function handleStyledTextSetJustification( menubar, stext, justification ) {
stext.node.style.textAlign = justification;
menuBarUpdateRadioMenuItems( menubar );
menuBarClose( menubar );
stext.node.focus();
}
/**
* handleStyledTextSetFontSize
* handlers changing
*
* @param ( MenuBar object) styled text to hav its font changed
* @param ( StyledText object) styled text to hav its font changed
* @return nothing
*/
function handleStyledTextSetFontSize( menubar, stext, size ) {
stext.fontSize = size;
stext.node.style.fontSize = stext.fontSizes[stext.fontSize];
menuBarUpdateRadioMenuItems( menubar );
menuBarClose( menubar );
stext.node.focus();
}
/**
* handleStyledTextFontSizeLarger
* handlers changing
*
* @param ( MenuBar object) styled text to hav its font changed
* @param ( StyledText object) styled text to hav its font changed
* @return nothing
*/
function handleStyledTextFontSizeLarger( menubar, stext) {
stext.fontSize++;
if( stext.fontSize > 4 )
stext.fontSize = 4;
menubar.current_menuitem_node = document.getElementById(stext.menu_item_ids[stext.fontSize]);
handleStyledTextSetFontSize( menubar, stext, stext.fontSize )
menuBarClose( menubar );
stext.node.focus();
}
/**
* handleStyledTextFontSizeSmaller
* handlers changing
*
* @param ( MenuBar object) styled text to hav its font changed
* @param ( StyledText object) styled text to hav its font changed
* @return nothing
*/
function handleStyledTextFontSizeSmaller( menubar, stext) {
stext.fontSize--;
if( stext.fontSize < 0 )
stext.fontSize = 0;
menubar.current_menuitem_node = document.getElementById(stext.menu_item_ids[stext.fontSize]);
handleStyledTextSetFontSize( menubar, stext, stext.fontSize )
menuBarClose( menubar );
stext.node.focus();
}
/**
* handleStyledTextBold
* handlers changing
*
* @param ( MenuBar object) styled text to hav its font changed
* @param ( StyledText object) styled text to hav its font changed
* @return nothing
*/
function handleStyledTextToggleBold( menubar, stext ) {
if( stext.node.style.fontWeight == "bold" ) {
stext.node.style.fontWeight = "normal";
menuBarUpdateCheckboxMenuItems( menubar, false );
} else {
stext.node.style.fontWeight = "bold";
menuBarUpdateCheckboxMenuItems( menubar, true );
} // endif
menuBarClose( menubar );
stext.node.focus();
}
/**
* handleStyledTextItalic
* handlers changing
*
* @param ( MenuBar object) styled text to hav its font changed
* @param ( StyledText object) styled text to hav its font changed
* @return nothing
*/
function handleStyledTextToggleItalic( menubar, stext ) {
if( stext.node.style.fontStyle == "italic" ) {
stext.node.style.fontStyle = "normal";
menuBarUpdateCheckboxMenuItems( menubar, false );
} else {
stext.node.style.fontStyle = "italic";
menuBarUpdateCheckboxMenuItems( menubar, true );
} // endif
menuBarClose( menubar );
stext.node.focus();
}
/**
* handleStyledTextUnderline
* handlers changing
*
* @param ( MenuBar object) styled text to hav its font changed
* @param ( StyledText object) styled text to hav its font changed
* @return nothing
*/
function handleStyledTextToggleUnderline( menubar, stext ) {
if( stext.node.style.textDecoration == "underline" ) {
stext.node.style.textDecoration = "none";
menuBarUpdateCheckboxMenuItems( menubar, false );
} else {
stext.node.style.textDecoration = "underline";
menuBarUpdateCheckboxMenuItems( menubar, true );
} // endif
menuBarClose( menubar );
stext.node.focus();
}
</script>
</head>
<body onload="widgets.init()">
<div role="application">
<script type="text/javascript">
var menubar1 = new MenuBar("mb1");
widgets.add(menubar1);
var stext1 = new StyledText("st1", ['mi1440', 'mi1450', 'mi1460', 'mi1470', 'mi1480'], menubar1);
widgets.add(stext1);
</script>
<dl id="mb1"
class="axs menubar tabindex-0"
title="Styling Menu">
<dt id="mi1100"
class="axs menuitem tabindex--1 haspopup-true"
>Font</dt>
<dd>
<dl id="m11"
class="axs menu">
<dt id="mi1110"
class="checked axs menuitemradio tabindex--1 checked-true"
onclick="handleStyledTextSetFontFamily(menubar1, stext1, 'Sans-serif')"
>Sans-serif</dt>
<dt id="mi1120"
class="axs menuitemradio tabindex--1 checked-false"
onclick="handleStyledTextSetFontFamily(menubar1, stext1, 'serif')">Serif</dt>
<dt id="mi1130"
class="axs menuitemradio tabindex--1 checked-false"
onclick="handleStyledTextSetFontFamily(menubar1, stext1, 'monospace')">Monospace</dt>
<dt id="mi1140"
class="axs menuitemradio tabindex--1 checked-false"
onclick="handleStyledTextSetFontFamily(menubar1, stext1, 'fantasy')">Fantasy</dt>
</dl>
</dd>
<dt id="mi1200"
class="axs menuitem tabindex--1 haspopup-true"
>Style</dt>
<dd>
<dl id="m12"
class="closed"
role="menu">
<dt id="mi1210"
class="axs menuitemcheckbox tabindex--1"
onclick="handleStyledTextToggleItalic(menubar1, stext1)">Italics</dt>
<dt id="mi1220"
class="axs menuitemcheckbox tabindex--1"
onclick="handleStyledTextToggleBold(menubar1, stext1)">Bold</dt>
<dt id="mi1230"
class="axs menuitemcheckbox tabindex--1"
onclick="handleStyledTextToggleUnderline(menubar1, stext1)">Underline</dt>
</dl>
</dd>
<dt id="mi1300"
class="axs menuitem tabindex--1 haspopup-true"
>Jusfication</dt>
<dd>
<dl id="m13"
class="closed axs menu"
title="Justication">
<dt id="mi1310"
class="checked axs menuitemradio tabindex--1 checked-true"
onclick="handleStyledTextSetJustification( menubar1, stext1, 'left' )"
class="checked">Left</dt>
<dt id="mi1320"
class="axs menuitemradio tabindex--1 checked-false"
onclick="handleStyledTextSetJustification( menubar1, stext1, 'center' )">Centered</dt>
<dt id="mi1330"
class="axs menuitemradio tabindex--1 checked-false"
onclick="handleStyledTextSetJustification( menubar1, stext1, 'right' )">Right</dt>
<dt id="mi1340"
class="axs menuitemradio tabindex--1 checked-false"
onclick="handleStyledTextSetJustification( menubar1, stext1, 'justify' )">Justify</dt>
</dl>
</dd>
<dt id="mi1400"
class="axs menuitem tabindex--1 haspopup-true"
>Size</dt>
<dd>
<dl id="m14"
class="closed axs menu"
title="Size">
<dt id="mi1410"
class="axs menuitem tabindex--1"
onclick="handleStyledTextFontSizeLarger( menubar1, stext1)">Larger</dt>
<dt id="mi1420"
class="axs menuitem tabindex--1"
onclick="handleStyledTextFontSizeSmaller( menubar1, stext1)">Smaller</dt>
<dt id="mi1430"
class="separator axs aria-separator tabindex--1"
class="separator"></dt>
<dt id="mi1440"
class="axs menuitemradio tabindex--1 checked-false"
onclick="handleStyledTextSetFontSize( menubar1, stext1, 0)">X-Small</dt>
<dt id="mi1450"
class="axs menuitemradio tabindex--1 checked-false"
onclick="handleStyledTextSetFontSize( menubar1, stext1, 1)">Small</dt>
<dt id="mi1460"
class="checked axs menuitemradio tabindex--1 checked-true"
onclick="handleStyledTextSetFontSize( menubar1, stext1, 2)">Medium</dt>
<dt id="mi1470"
class="axs menuitemradio tabindex--1 checked-false"
onclick="handleStyledTextSetFontSize( menubar1, stext1, 3)">Large</dt>
<dt id="mi1480"
class="axs menuitemradio tabindex--1 checked-false"
onclick="handleStyledTextSetFontSize( menubar1, stext1, 4)">X-Large</dt>
</dl>
</dd>
</dl>
<textarea id="st1" name="st1" style="padding: .5em; border: thin black solid; height: 30em; width: 40em; font-family: sans-serif">
Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal.
Now we are engaged in a great civil war, testing whether that nation, or any nation, so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.
But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow, this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us, that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion, that we here highly resolve that these dead shall not have died in vain, that this nation, under God, shall have a new birth of freedom, and that government of the people, by the people, for the people, shall not perish from the earth.
</textarea>
<p><a href="http://en.wikipedia.org/wiki/Gettysburg,_Pennsylvania">More information on Gettysburg Address</a></p>
</div></body>
</html>