braille_util.js revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @fileoverview A utility class for general braille functionality. 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.provide('cvox.BrailleUtil'); 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.ChromeVox'); 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.DomUtil'); 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.Focuser'); 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.NavBraille'); 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.NodeStateUtil'); 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.Spannable'); 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Trimmable whitespace character that appears between consecutive items in 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * braille. 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @const {string} 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.ITEM_SEPARATOR = ' '; 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Messages considered as containers in braille. 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Containers are distinguished from roles by their appearance higher up in the 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * DOM tree of a selected node. 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * This list should be very short. 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {!Array.<string>} 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.CONTAINER = [ 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'tag_h1_brl', 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'tag_h2_brl', 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'tag_h3_brl', 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'tag_h4_brl', 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'tag_h5_brl', 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'tag_h6_brl' 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)]; 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Maps a ChromeVox message id to a braille template. 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The template takes one-character specifiers: 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * n: replaced with braille name. 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * r: replaced with braille role. 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * s: replaced with braille state. 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * c: replaced with braille container role; this potentially returns whitespace, 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * so place at the beginning or end of templates for trimming. 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * v: replaced with braille value. 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {Object.<string, string>} 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.TEMPLATE = { 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'base': 'c n v r s', 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'aria_role_alert': 'r: n', 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'aria_role_button': '[n]', 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'aria_role_textbox': 'n: v r', 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'input_type_button': '[n]', 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'input_type_checkbox': 'n (s)', 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'input_type_email': 'n: v r', 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'input_type_number': 'n: v r', 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'input_type_password': 'n: v r', 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'input_type_search': 'n: v r', 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'input_type_submit': '[n]', 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'input_type_text': 'n: v r', 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'input_type_tel': 'n: v r', 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'input_type_url': 'n: v r', 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'tag_button': '[n]', 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'tag_textarea': 'n: v r' 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Attached to the value region of a braille spannable. 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number} offset The offset of the span into the value. 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @constructor 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @struct 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.ValueSpan = function(offset) { 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The offset of the span into the value. 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {number} 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.offset = offset; 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Creates a value span from a json serializable object. 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {!Object} obj The json serializable object to convert. 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!cvox.BrailleUtil.ValueSpan} 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.ValueSpan.fromJson = function(obj) { 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return new cvox.BrailleUtil.ValueSpan(obj.offset); 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Converts this object to a json serializable object. 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!Object} 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.ValueSpan.prototype.toJson = function() { 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return this; 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.Spannable.registerSerializableSpan( 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.ValueSpan, 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'cvox.BrailleUtil.ValueSpan', 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.ValueSpan.fromJson, 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.ValueSpan.prototype.toJson); 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Attached to the selected text within a value. 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @constructor 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @struct 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.ValueSelectionSpan = function() { 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.Spannable.registerStatelessSerializableSpan( 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.ValueSelectionSpan, 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'cvox.BrailleUtil.ValueSelectionSpan'); 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille name for a node. 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * See DomUtil for a more precise definition of 'name'. 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Additionally, whitespace is trimmed. 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The string representation. 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getName = function(node) { 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!node) { 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return cvox.DomUtil.getName(node).trim(); 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille role message id for a node. 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * See DomUtil for a more precise definition of 'role'. 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The string representation. 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getRoleMsg = function(node) { 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!node) { 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var roleMsg = cvox.DomUtil.getRoleMsg(node, cvox.VERBOSITY_VERBOSE); 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (roleMsg) { 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) roleMsg = cvox.DomUtil.collapseWhitespace(roleMsg); 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (roleMsg && (roleMsg.length > 0)) { 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cvox.ChromeVox.msgs.getMsg(roleMsg + '_brl')) { 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) roleMsg += '_brl'; 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return roleMsg; 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille role of a node. 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * See DomUtil for a more precise definition of 'role'. 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The string representation. 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getRole = function(node) { 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!node) { 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var roleMsg = cvox.BrailleUtil.getRoleMsg(node); 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return roleMsg ? cvox.ChromeVox.msgs.getMsg(roleMsg) : ''; 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille state of a node. 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The string representation. 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getState = function(node) { 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!node) { 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return cvox.NodeStateUtil.expand( 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.DomUtil.getStateMsgs(node, true).map(function(state) { 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Check to see if a variant of the message with '_brl' exists, 19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // and use it if so. 19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Note: many messages are templatized, and if we don't pass any 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // argument to substitute, getMsg might throw an error if the 20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // resulting string is empty. To avoid this, we pass a dummy 20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // substitution string array here. 20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) var dummySubs = ['dummy', 'dummy', 'dummy']; 20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (cvox.ChromeVox.msgs.getMsg(state[0] + '_brl', dummySubs)) { 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state[0] += '_brl'; 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return state; 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) })); 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille container role of a node. 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} prev The previous node in navigation. 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The string representation. 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getContainer = function(prev, node) { 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!prev || !node) { 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var ancestors = cvox.DomUtil.getUniqueAncestors(prev, node); 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (var i = 0, container; container = ancestors[i]; i++) { 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var msg = cvox.BrailleUtil.getRoleMsg(container); 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg && cvox.BrailleUtil.CONTAINER.indexOf(msg) != -1) { 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return cvox.ChromeVox.msgs.getMsg(msg); 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille value of a node. A cvox.BrailleUtil.ValueSpan will be 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * attached, along with (possibly) a cvox.BrailleUtil.ValueSelectionSpan. 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!cvox.Spannable} The value spannable. 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getValue = function(node) { 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!node) { 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return new cvox.Spannable(); 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var valueSpan = new cvox.BrailleUtil.ValueSpan(0 /* offset */); 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cvox.DomUtil.isInputTypeText(node)) { 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var value = node.value; 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (node.type === 'password') { 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) value = value.replace(/./g, '*'); 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var spannable = new cvox.Spannable(value, valueSpan); 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (node === document.activeElement && 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.DomUtil.doesInputSupportSelection(node)) { 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var selectionStart = cvox.BrailleUtil.clamp_( 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node.selectionStart, 0, spannable.getLength()); 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var selectionEnd = cvox.BrailleUtil.clamp_( 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node.selectionEnd, 0, spannable.getLength()); 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spannable.setSpan(new cvox.BrailleUtil.ValueSelectionSpan(), 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Math.min(selectionStart, selectionEnd), 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Math.max(selectionStart, selectionEnd)); 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return spannable; 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (node instanceof HTMLTextAreaElement) { 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var shadow = new cvox.EditableTextAreaShadow(); 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) shadow.update(node); 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var lineIndex = shadow.getLineIndex(node.selectionEnd); 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var lineStart = shadow.getLineStart(lineIndex); 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var lineEnd = shadow.getLineEnd(lineIndex); 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var lineText = node.value.substring(lineStart, lineEnd); 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) valueSpan.offset = lineStart; 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var spannable = new cvox.Spannable(lineText, valueSpan); 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (node === document.activeElement) { 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var selectionStart = cvox.BrailleUtil.clamp_( 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node.selectionStart - lineStart, 0, spannable.getLength()); 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var selectionEnd = cvox.BrailleUtil.clamp_( 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node.selectionEnd - lineStart, 0, spannable.getLength()); 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spannable.setSpan(new cvox.BrailleUtil.ValueSelectionSpan(), 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Math.min(selectionStart, selectionEnd), 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Math.max(selectionStart, selectionEnd)); 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return spannable; 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return new cvox.Spannable(cvox.DomUtil.getValue(node), valueSpan); 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the templated representation of braille. 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} prev The previous node (during navigation). 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {{name:(undefined|string), 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * role:(undefined|string), 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * roleMsg:(undefined|string), 292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * state:(undefined|string), 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * container:(undefined|string), 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * value:(undefined|cvox.Spannable)}|Object=} opt_override Override a 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * specific property for the given node. 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!cvox.Spannable} The string representation. 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getTemplated = function(prev, node, opt_override) { 299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_override = opt_override ? opt_override : {}; 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var roleMsg = opt_override.roleMsg || 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (node ? cvox.DomUtil.getRoleMsg(node, cvox.VERBOSITY_VERBOSE) : ''); 302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var role = opt_override.role; 303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!role && opt_override.roleMsg) { 304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) role = cvox.ChromeVox.msgs.getMsg(opt_override.roleMsg + '_brl') || 305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.msgs.getMsg(opt_override.roleMsg); 306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) role = role || cvox.BrailleUtil.getRole(node); 308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var template = cvox.BrailleUtil.TEMPLATE[roleMsg] || 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.TEMPLATE['base']; 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var templated = new cvox.Spannable(); 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var mapChar = function(c) { 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (c) { 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'n': 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return opt_override.name || cvox.BrailleUtil.getName(node); 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'r': 317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return role; 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 's': 319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return opt_override.state || cvox.BrailleUtil.getState(node); 320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'c': 321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return opt_override.container || 322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.getContainer(prev, node); 323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'v': 324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return opt_override.value || cvox.BrailleUtil.getValue(node); 325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return c; 327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (var i = 0; i < template.length; i++) { 330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var component = mapChar(template[i]); 331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) templated.append(component); 332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Ignore the next whitespace separator if the current component is empty. 333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!component.toString() && template[i + 1] == ' ') { 334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) i++; 335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return templated.trimRight(); 338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Creates a braille value from a string and, optionally, a selection range. 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * A cvox.BrailleUtil.ValueSpan will be 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * attached, along with a cvox.BrailleUtil.ValueSelectionSpan if applicable. 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string} text The text to display as the value. 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number=} opt_selStart Selection start. 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number=} opt_selEnd Selection end if different from selection start. 348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number=} opt_textOffset Start offset of text. 349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!cvox.Spannable} The value spannable. 350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.createValue = function(text, opt_selStart, opt_selEnd, 352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_textOffset) { 353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var spannable = new cvox.Spannable( 354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) text, new cvox.BrailleUtil.ValueSpan(opt_textOffset || 0)); 355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.isDef(opt_selStart)) { 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_selEnd = goog.isDef(opt_selEnd) ? opt_selEnd : opt_selStart; 357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(plundblad): This looses the distinction between the selection 358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // anchor (start) and focus (end). We should use that information to 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // decide where to pan the braille display. 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opt_selStart > opt_selEnd) { 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var temp = opt_selStart; 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_selStart = opt_selEnd; 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_selEnd = temp; 364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spannable.setSpan(new cvox.BrailleUtil.ValueSelectionSpan(), 367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_selStart, opt_selEnd); 368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return spannable; 370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Activates a position in a nav braille. Moves the caret in text fields 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * and simulates a mouse click on the node at the position. 376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {!cvox.NavBraille} braille the nav braille representing the display 378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * content that was active when the user issued the key command. 379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The annotations in the spannable are used to decide what 380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * node to activate and what part of the node value (if any) to 381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * move the caret to. 382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number=} opt_displayPosition position of the display that the user 383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * activated, relative to the start of braille. 384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.click = function(braille, opt_displayPosition) { 386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var spans = braille.text.getSpans(opt_displayPosition || 0); 387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var node = spans.filter(function(n) { return n instanceof Node; })[0]; 388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (node) { 389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.Focuser.setFocus(node); 390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.isDef(opt_displayPosition) && 391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (cvox.DomUtil.isInputTypeText(node) || 392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node instanceof HTMLTextAreaElement)) { 393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var valueSpan = spans.filter( 394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) function(s) { 395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return s instanceof cvox.BrailleUtil.ValueSpan; 396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) })[0]; 397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (valueSpan) { 398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var cursorPosition = opt_displayPosition - 399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) braille.text.getSpanStart(valueSpan) + 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) valueSpan.offset; 401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVoxEventWatcher.setUpTextHandler(); 402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node.selectionStart = node.selectionEnd = cursorPosition; 403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVoxEventWatcher.handleTextChanged(true); 404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.DomUtil.clickElem(node || 408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.navigationManager.getCurrentNode(), false, false); 409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Clamps a number so it is within the given boundaries. 414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number} number The number to clamp. 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number} min The minimum value to return. 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number} max The maximum value to return. 417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {number} {@code number} if it is within the bounds, or the nearest 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * number within the bounds otherwise. 419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.clamp_ = function(number, min, max) { 422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return Math.min(Math.max(number, min), max); 423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 424