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) */ 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.ValueSpan = function(offset) { 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The offset of the span into the value. 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {number} 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.offset = offset; 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Creates a value span from a json serializable object. 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {!Object} obj The json serializable object to convert. 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {!cvox.BrailleUtil.ValueSpan} The value span. 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.ValueSpan.fromJson = function(obj) { 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return new cvox.BrailleUtil.ValueSpan(obj.offset); 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Converts this object to a json serializable object. 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {!Object} The JSON representation. 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.ValueSpan.prototype.toJson = function() { 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return this; 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.Spannable.registerSerializableSpan( 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.ValueSpan, 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'cvox.BrailleUtil.ValueSpan', 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.ValueSpan.fromJson, 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.ValueSpan.prototype.toJson); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Attached to the selected text within a value. 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @constructor 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.ValueSelectionSpan = function() { 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.Spannable.registerStatelessSerializableSpan( 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.ValueSelectionSpan, 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'cvox.BrailleUtil.ValueSelectionSpan'); 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille name for a node. 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * See DomUtil for a more precise definition of 'name'. 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Additionally, whitespace is trimmed. 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The string representation. 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getName = function(node) { 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!node) { 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return cvox.DomUtil.getName(node).trim(); 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille role message id for a node. 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * See DomUtil for a more precise definition of 'role'. 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The string representation. 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getRoleMsg = function(node) { 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!node) { 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var roleMsg = cvox.DomUtil.getRoleMsg(node, cvox.VERBOSITY_VERBOSE); 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (roleMsg) { 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) roleMsg = cvox.DomUtil.collapseWhitespace(roleMsg); 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (roleMsg && (roleMsg.length > 0)) { 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cvox.ChromeVox.msgs.getMsg(roleMsg + '_brl')) { 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) roleMsg += '_brl'; 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return roleMsg; 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille role of a node. 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * See DomUtil for a more precise definition of 'role'. 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The string representation. 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getRole = function(node) { 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!node) { 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var roleMsg = cvox.BrailleUtil.getRoleMsg(node); 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return roleMsg ? cvox.ChromeVox.msgs.getMsg(roleMsg) : ''; 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille state of a node. 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The string representation. 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getState = function(node) { 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!node) { 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return cvox.NodeStateUtil.expand( 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.DomUtil.getStateMsgs(node, true).map(function(state) { 19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Check to see if a variant of the message with '_brl' exists, 19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // and use it if so. 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // 19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Note: many messages are templatized, and if we don't pass any 19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // argument to substitute, getMsg might throw an error if the 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // resulting string is empty. To avoid this, we pass a dummy 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // substitution string array here. 20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) var dummySubs = ['dummy', 'dummy', 'dummy']; 20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (cvox.ChromeVox.msgs.getMsg(state[0] + '_brl', dummySubs)) { 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state[0] += '_brl'; 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return state; 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) })); 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille container role of a node. 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} prev The previous node in navigation. 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The string representation. 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getContainer = function(prev, node) { 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!prev || !node) { 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var ancestors = cvox.DomUtil.getUniqueAncestors(prev, node); 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (var i = 0, container; container = ancestors[i]; i++) { 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var msg = cvox.BrailleUtil.getRoleMsg(container); 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg && cvox.BrailleUtil.CONTAINER.indexOf(msg) != -1) { 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return cvox.ChromeVox.msgs.getMsg(msg); 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ''; 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the braille value of a node. A cvox.BrailleUtil.ValueSpan will be 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * attached, along with (possibly) a cvox.BrailleUtil.ValueSelectionSpan. 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!cvox.Spannable} The value spannable. 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getValue = function(node) { 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!node) { 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return new cvox.Spannable(); 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var valueSpan = new cvox.BrailleUtil.ValueSpan(0 /* offset */); 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cvox.DomUtil.isInputTypeText(node)) { 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var value = node.value; 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (node.type === 'password') { 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) value = value.replace(/./g, '*'); 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var spannable = new cvox.Spannable(value, valueSpan); 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (node === document.activeElement && 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.DomUtil.doesInputSupportSelection(node)) { 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var selectionStart = cvox.BrailleUtil.clamp_( 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node.selectionStart, 0, spannable.getLength()); 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var selectionEnd = cvox.BrailleUtil.clamp_( 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node.selectionEnd, 0, spannable.getLength()); 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spannable.setSpan(new cvox.BrailleUtil.ValueSelectionSpan(), 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Math.min(selectionStart, selectionEnd), 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Math.max(selectionStart, selectionEnd)); 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return spannable; 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (node instanceof HTMLTextAreaElement) { 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var shadow = new cvox.EditableTextAreaShadow(); 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) shadow.update(node); 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var lineIndex = shadow.getLineIndex(node.selectionEnd); 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var lineStart = shadow.getLineStart(lineIndex); 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var lineEnd = shadow.getLineEnd(lineIndex); 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var lineText = node.value.substring(lineStart, lineEnd); 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) valueSpan.offset = lineStart; 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var spannable = new cvox.Spannable(lineText, valueSpan); 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (node === document.activeElement) { 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var selectionStart = cvox.BrailleUtil.clamp_( 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node.selectionStart - lineStart, 0, spannable.getLength()); 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var selectionEnd = cvox.BrailleUtil.clamp_( 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node.selectionEnd - lineStart, 0, spannable.getLength()); 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spannable.setSpan(new cvox.BrailleUtil.ValueSelectionSpan(), 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Math.min(selectionStart, selectionEnd), 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Math.max(selectionStart, selectionEnd)); 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return spannable; 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return new cvox.Spannable(cvox.DomUtil.getValue(node), valueSpan); 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the templated representation of braille. 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} prev The previous node (during navigation). 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Node} node The node. 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {{name:(undefined|string), 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * role:(undefined|string), 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * roleMsg:(undefined|string), 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * state:(undefined|string), 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * container:(undefined|string), 292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * value:(undefined|cvox.Spannable)}|Object=} opt_override Override a 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * specific property for the given node. 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!cvox.Spannable} The string representation. 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.getTemplated = function(prev, node, opt_override) { 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_override = opt_override ? opt_override : {}; 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var roleMsg = opt_override.roleMsg || 299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (node ? cvox.DomUtil.getRoleMsg(node, cvox.VERBOSITY_VERBOSE) : ''); 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var role = opt_override.role; 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!role && opt_override.roleMsg) { 302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) role = cvox.ChromeVox.msgs.getMsg(opt_override.roleMsg + '_brl') || 303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.msgs.getMsg(opt_override.roleMsg); 304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) role = role || cvox.BrailleUtil.getRole(node); 306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var template = cvox.BrailleUtil.TEMPLATE[roleMsg] || 307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.TEMPLATE['base']; 308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var templated = new cvox.Spannable(); 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var mapChar = function(c) { 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (c) { 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'n': 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return opt_override.name || cvox.BrailleUtil.getName(node); 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'r': 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return role; 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 's': 317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return opt_override.state || cvox.BrailleUtil.getState(node); 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'c': 319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return opt_override.container || 320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleUtil.getContainer(prev, node); 321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'v': 322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return opt_override.value || cvox.BrailleUtil.getValue(node); 323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return c; 325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (var i = 0; i < template.length; i++) { 328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var component = mapChar(template[i]); 329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) templated.append(component); 330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Ignore the next whitespace separator if the current component is empty. 331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!component.toString() && template[i + 1] == ' ') { 332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) i++; 333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return templated.trimRight(); 336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Creates a braille value from a string and, optionally, a selection range. 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * A cvox.BrailleUtil.ValueSpan will be 342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * attached, along with a cvox.BrailleUtil.ValueSelectionSpan if applicable. 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string} text The text to display as the value. 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number=} opt_selStart Selection start. 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number=} opt_selEnd Selection end if different from selection start. 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number=} opt_textOffset Start offset of text. 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!cvox.Spannable} The value spannable. 348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.createValue = function(text, opt_selStart, opt_selEnd, 350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_textOffset) { 351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var spannable = new cvox.Spannable( 352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) text, new cvox.BrailleUtil.ValueSpan(opt_textOffset || 0)); 353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.isDef(opt_selStart)) { 354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_selEnd = goog.isDef(opt_selEnd) ? opt_selEnd : opt_selStart; 355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(plundblad): This looses the distinction between the selection 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // anchor (start) and focus (end). We should use that information to 357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // decide where to pan the braille display. 358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (opt_selStart > opt_selEnd) { 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var temp = opt_selStart; 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_selStart = opt_selEnd; 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_selEnd = temp; 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spannable.setSpan(new cvox.BrailleUtil.ValueSelectionSpan(), 365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_selStart, opt_selEnd); 366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return spannable; 368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Activates a position in a nav braille. Moves the caret in text fields 373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * and simulates a mouse click on the node at the position. 374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {!cvox.NavBraille} braille the nav braille representing the display 376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * content that was active when the user issued the key command. 377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The annotations in the spannable are used to decide what 378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * node to activate and what part of the node value (if any) to 379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * move the caret to. 380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number=} opt_displayPosition position of the display that the user 381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * activated, relative to the start of braille. 382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.click = function(braille, opt_displayPosition) { 384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var handled = false; 385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var spans = braille.text.getSpans(opt_displayPosition || 0); 386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var node = spans.filter(function(n) { return n instanceof Node; })[0]; 387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (node) { 388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.isDef(opt_displayPosition) && 389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (cvox.DomUtil.isInputTypeText(node) || 390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node instanceof HTMLTextAreaElement)) { 391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var valueSpan = spans.filter( 392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) function(s) { 393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return s instanceof cvox.BrailleUtil.ValueSpan; 394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) })[0]; 395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (valueSpan) { 396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (document.activeElement !== node) { 397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cvox.Focuser.setFocus(node); 398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var cursorPosition = opt_displayPosition - 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) braille.text.getSpanStart(valueSpan) + 401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) valueSpan.offset; 402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVoxEventWatcher.setUpTextHandler(); 403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) node.selectionStart = node.selectionEnd = cursorPosition; 404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVoxEventWatcher.handleTextChanged(true); 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch handled = true; 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!handled) { 410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cvox.DomUtil.clickElem( 411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch node || cvox.ChromeVox.navigationManager.getCurrentNode(), 412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch false, false, false, true); 413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Clamps a number so it is within the given boundaries. 419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number} number The number to clamp. 420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number} min The minimum value to return. 421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {number} max The maximum value to return. 422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {number} {@code number} if it is within the bounds, or the nearest 423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * number within the bounds otherwise. 424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.BrailleUtil.clamp_ = function(number, min, max) { 427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return Math.min(Math.max(number, min), max); 428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 429