Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(904)

Unified Diff: chrome/browser/resources/access_chromevox/scripts/axsjax/axsjax.js

Issue 6254007: Adding ChromeVox as a component extensions (enabled only for ChromeOS, for no... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/access_chromevox/scripts/axsjax/axsjax.js
===================================================================
--- chrome/browser/resources/access_chromevox/scripts/axsjax/axsjax.js (revision 0)
+++ chrome/browser/resources/access_chromevox/scripts/axsjax/axsjax.js (revision 0)
@@ -0,0 +1,381 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+goog.provide('cvox.AxsJAX');
+
+goog.require('cvox.ChromeVox');
+goog.require('cvox.DomUtil');
+goog.require('cvox.XpathUtil');
+
+/**
+ * @fileoverview AxsJAX - JavaScript library for enhancing the accessibility
+ * of AJAX apps through WAI-ARIA.
+ * Note that this is a ChromeVox specific version of AxsJAX that has been
+ * optimized and refactored for ChromeVox.
+ */
+
+/**
+ * Class of scripts for improving accessibility of Web 2.0 Apps.
+ * @param {boolean} useTabKeyFix Whether or not to try syncing to the last
+ * marked position when the user presses the
+ * tab key.
+ * @constructor
+ */
+cvox.AxsJAX = function(useTabKeyFix) {
+ this.ID_NUM_ = 0;
+ this.tabbingStartPosNode_ = null;
+ this.tabKeyFixOn_ = false;
+ this.lastFocusedNode = null;
+ this.inputFocused = false;
+
+ var self = this;
+
+ //Monitor focus and blur
+ this.addFocusBlurMonitors();
+
+ //Activate the tab key fix if needed
+ if (useTabKeyFix) {
+ this.tabKeyFixOn_ = true;
+ document.addEventListener('keypress',
+ function(event) {
+ self.tabKeyHandler(event, self);
+ },
+ true);
+ // Record in a custom DOM property:
+ document.body.AXSJAX_TABKEYFIX_ADDED = true;
+ }
+};
+
+
+/**
+ * Adds focus/blur handlers to the current active document.
+ * This should be invoked when AxsJAX is first initialized and
+ * when a new active document has been set.
+ */
+cvox.AxsJAX.prototype.addFocusBlurMonitors = function() {
+ var activeDoc = this.getActiveDocument();
+ var self = this;
+ //These return "true" so that any page actions based on
+ //focus and blur will still occur.
+ var focusHandler = function(evt) {
+ self.lastFocusedNode = evt.target;
+ if ((evt.target.tagName == 'INPUT') ||
+ (evt.target.tagName == 'SELECT') ||
+ (evt.target.tagName == 'TEXTAREA')) {
+ self.inputFocused = true;
+ }
+ return true;
+ };
+ activeDoc.addEventListener('focus', focusHandler, true);
+
+ var blurHandler = function(evt) {
+ self.lastFocusedNode = null;
+ if ((evt.target.tagName == 'INPUT') ||
+ (evt.target.tagName == 'SELECT') ||
+ (evt.target.tagName == 'TEXTAREA')) {
+ self.inputFocused = false;
+ }
+ return true;
+ };
+ activeDoc.addEventListener('blur', blurHandler, true);
+};
+
+
+/**
+ * This function is not needed in Chrome Vox and is a no-op. It is available
+ * only as a compatibility shim for existing AxsJAX scripts.
+ *
+ * @param {Node} targetNode Dummy node - this is not used.
+ */
+cvox.AxsJAX.prototype.setActiveParent = function(targetNode) {
+};
+
+
+/**
+ * This function is not needed in Chrome Vox and is the same as just calling
+ * "document".
+ * Gets the document for the active parent.
+ * @return {Node} The document that is the ancestor for the active parent.
+ */
+cvox.AxsJAX.prototype.getActiveDocument = function() {
+ return document;
+};
+
+
+/**
+ * Speaks a given node using ChromeVox.
+ * @param {Node} targetNode The HTML node to be spoken.
+ */
+cvox.AxsJAX.prototype.speakNode = function(targetNode) {
+ ChromeVox.tts.speak(DomUtil.getText(targetNode), 0, null);
+};
+
+
+/**
+ * Speaks the given textString using ChromeVox.
+ * @param {String} textString The text to be spoken.
+ */
+cvox.AxsJAX.prototype.speakText = function(textString) {
+ ChromeVox.tts.speak(textString, 0, null);
+};
+
+/**
+ * Speaks the given textString using ChromeVox.
+ * This function is the same as speakText as is available only as a
+ * compatibility shim for existing AxsJAX scripts.
+ *
+ * @param {String} textString The text to be spoken.
+ *
+ */
+cvox.AxsJAX.prototype.speakTextViaNode = function(textString) {
+ ChromeVox.tts.speak(textString, 0, null);
+};
+
+/**
+ * Puts alt='' for all images that are children of the target node that
+ * have no alt text defined. This is a bandage fix to prevent screen readers
+ * from rambling on by reading the URL string of the image.
+ * A real fix for this problem should be to either use appropriate alt text for
+ * the images or explicitly put alt='' for images that have no semantic value.
+ * @param {Node} targetNode The target node of this operation.
+ */
+cvox.AxsJAX.prototype.putNullForNoAltImages = function(targetNode) {
+ var images = targetNode.getElementsByTagName('img');
+ for (var i = 0, image; image = images[i]; i++) {
+ if (!image.alt) {
+ image.alt = '';
+ }
+ }
+};
+
+
+/**
+ * Dispatches a left click event on the element that is the targetNode.
+ * Clicks go in the sequence of mousedown, mouseup, and click.
+ * This functionality already exists in DomUtil, so this method simply
+ * redirects to that.
+ *
+ * @param {Node} targetNode The target node of this operation.
+ * @param {boolean} shiftKey Specifies if shift is held down.
+ */
+cvox.AxsJAX.prototype.clickElem = function(targetNode, shiftKey) {
+ DomUtil.clickElem(targetNode, shiftKey);
+};
+
+/**
+ * Dispatches a key event on the element that is the targetNode.
+ * @param {Node} targetNode The target node of this operation.
+ * @param {String} theKey The key to use for this operation.
+ * This can be any single printable character or ENTER.
+ * @param {Boolean} holdCtrl Whether or not the Ctrl key should be held for
+ * this operation.
+ * @param {Boolean} holdAlt Whether or not the Alt key should be held for
+ * this operation.
+ * @param {Boolean} holdShift Whether or not the Shift key should be held
+ * for this operation.
+ */
+cvox.AxsJAX.prototype.sendKey = function(targetNode, theKey,
+ holdCtrl, holdAlt, holdShift) {
+ var keyCode = 0;
+ var charCode = 0;
+ if (theKey == 'ENTER') {
+ keyCode = 13;
+ }
+ else if (theKey.length == 1) {
+ charCode = theKey.charCodeAt(0);
+ }
+ var activeDoc = this.getActiveDocument();
+ var evt = activeDoc.createEvent('KeyboardEvent');
+ evt.initKeyEvent('keypress', true, true, null, holdCtrl,
+ holdAlt, holdShift, false, keyCode, charCode);
+ targetNode.dispatchEvent(evt);
+};
+
+/**
+ * Assigns an ID to the targetNode.
+ * If targetNode already has an ID, this is a no-op.
+ * Always returns the ID of targetNode.
+ * If targetNode is null, we return ''
+ * @param {Node} targetNode The target node of this operation.
+ * @param {String} opt_prefixString
+ * Prefix to help ensure the uniqueness of the ID.
+ * This is optional; if null, it will use "AxsJAX_ID_".
+ * @return {string} The ID that the targetNode now has.
+ */
+cvox.AxsJAX.prototype.assignId = function(targetNode, opt_prefixString) {
+ if (!targetNode) {
+ return '';
+ }
+ if (targetNode.id) {
+ return targetNode.id;
+ }
+ var prefix = opt_prefixString || 'AxsJAX_ID_';
+ targetNode.id = prefix + this.ID_NUM_++;
+ return targetNode.id;
+};
+
+/**
+ * Marks the current position by remembering what the last focusable node was.
+ * The focusable node will be the targetNode if it has a focus() function, or
+ * if it does not, the first descendent node that it has which does.
+ * If the targetNode itself and all of its descendents have no focus() function,
+ * this function will complete with failure.
+ * If the cvox.AxsJAX.tabKeyHandler is used, then it will put the focus on this
+ * node.
+ * @param {Node} targetNode The target node of this operation.
+ * @return {Boolean} True if the position was marked successfully.
+ * False if failed.
+ */
+cvox.AxsJAX.prototype.markPosition = function(targetNode) {
+ if (!targetNode) {
+ return false;
+ }
+ ChromeVox.navigationManager.syncToNode(targetNode);
+ if ((targetNode.tagName == 'A') || (targetNode.tagName == 'INPUT')) {
+ this.tabbingStartPosNode_ = targetNode;
+ return true;
+ }
+ var allDescendants = targetNode.getElementsByTagName('*');
+ for (var i = 0, currentNode; currentNode = allDescendants[i]; i++) {
+ if ((currentNode.tagName == 'A') ||
+ (currentNode.tagName == 'INPUT') ||
+ (currentNode.hasAttribute('tabindex') &&
+ (currentNode.tabIndex != -1))) {
+ this.tabbingStartPosNode_ = currentNode;
+ return true;
+ }
+ }
+ return false;
+};
+
+/**
+ * Restores the focus .
+ * Usage:
+ * var myAxsJAXObj = new AxsJAX();
+ * document.addEventListener('keypress',
+ * function(event){
+ * myAxsJAXObj.tabKeyHandler(event,myAxsJAXObj);
+ * },
+ * true);
+ * @param {Event} evt The event.
+ * @param {Object} selfRef The AxsJAX object. A self reference is needed here
+ * since this in an event handler does NOT refer to the
+ * AxsJAX object.
+ * @return {Boolean} Always returns true to pass the tab key along.
+ */
+cvox.AxsJAX.prototype.tabKeyHandler = function(evt, selfRef) {
+ if (!selfRef.tabKeyFixOn_) {
+ return true;
+ }
+ if ((evt.keyCode == 9) && (selfRef.tabbingStartPosNode_)) {
+ selfRef.tabbingStartPosNode_.focus();
+ selfRef.tabbingStartPosNode_ = null;
+ }
+ return true;
+};
+
+/**
+ * Scrolls to the targetNode and speaks it.
+ * This will automatically mark the position; this should be used if you are
+ * navigating through content.
+ * @param {Node} targetNode The HTML node to be spoken.
+ */
+cvox.AxsJAX.prototype.goTo = function(targetNode) {
+ this.speakNode(targetNode);
+ targetNode.scrollIntoView(true);
+ this.markPosition(targetNode);
+};
+
+
+/**
+ * Sets the attribute of the targetNode to the value.
+ * Use this rather than a direct set attribute to abstract away ARIA
+ * naming changes.
+ * @param {Node} targetNode The HTML node to have the attribute set on.
+ * @param {string} attribute The attribute to set.
+ * @param {string?} value The value the attribute should be set to.
+ */
+cvox.AxsJAX.prototype.setAttributeOf = function(targetNode, attribute, value) {
+ if (!targetNode) {
+ return;
+ }
+ //Add the aria- to attributes
+ attribute = attribute.toLowerCase();
+ switch (attribute) {
+ case 'live':
+ attribute = 'aria-live';
+ break;
+ case 'activedescendant':
+ attribute = 'aria-activedescendant';
+ break;
+ case 'atomic':
+ attribute = 'aria-atomic';
+ break;
+ default:
+ break;
+ }
+ targetNode.setAttribute(attribute, value);
+};
+
+/**
+ * Gets the attribute of the targetNode.
+ * Use this rather than a direct get attribute to abstract away ARIA
+ * naming changes.
+ * @param {Node} targetNode The HTML node to get the attribute of.
+ * @param {string} attribute The attribute to get the value of.
+ * @return {string} The value of the attribute of the targetNode.
+ */
+cvox.AxsJAX.prototype.getAttributeOf = function(targetNode, attribute) {
+ return targetNode.getAttribute(attribute);
+};
+
+/**
+ * Removes the attribute of the targetNode.
+ * Use this rather than a direct remove attribute to abstract away ARIA
+ * naming changes.
+ * @param {Node} targetNode The HTML node to remove the attribute from.
+ * @param {string} attribute The attribute to be removed.
+ */
+cvox.AxsJAX.prototype.removeAttributeOf = function(targetNode, attribute) {
+ if (targetNode && targetNode.removeAttribute) {
+ targetNode.removeAttribute(attribute);
+ }
+};
+
+/**
+ * This is a no-op for ChromeVox since ChromeVox is the AT and does not need to
+ * be synced. This function is available only as a compatibility shim.
+ *
+ * @param {Node} targetNode The HTML node to force the AT to sync to.
+ */
+cvox.AxsJAX.prototype.forceATSync = function(targetNode) {
+
+};
+
+/**
+ * Given an XPath expression and rootNode, it returns an array of children nodes
+ * that match.
+ * This functionality already exists in XpathUtil, so this method simply
+ * redirects to that.
+ * @param {string} expression The XPath expression to evaluate.
+ * @param {Node} rootNode The HTML node to start evaluating the XPath from.
+ * @return {Array} The array of children nodes that match.
+ */
+cvox.AxsJAX.prototype.evalXPath = function(expression, rootNode) {
+ return cvox.XpathUtil.evalXPath(expression, rootNode);
+};
+
+/**
+ * This function initializes an AxsJAX script by calling a given initialization
+ * routine after the page load event has been generated. Using
+ * this method instead of attaching the event listener directly is recommended
+ * to enable testability of the application.
+ *
+ * @param {Function!} initFunction The initialization function to invoke.
+ */
+cvox.AxsJAX.initializeOnLoad = function(initFunction) {
+ window.addEventListener('load', function() {
+ initFunction();
+ }, true);
+};
Property changes on: chrome/browser/resources/access_chromevox/scripts/axsjax/axsjax.js
___________________________________________________________________
Added: svn:executable
+ *
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698