OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 /** |
| 6 * @fileoverview Provides output services for ChromeVox. |
| 7 */ |
| 8 |
| 9 goog.provide('Output'); |
| 10 |
| 11 goog.require('AutomationUtil.Dir'); |
| 12 goog.require('cursors.Cursor'); |
| 13 goog.require('cursors.Range'); |
| 14 goog.require('cursors.Unit'); |
| 15 |
| 16 /** @constructor */ |
| 17 Output = function() { |
| 18 /** @type {cursors.Range} @private */ |
| 19 this.prevRange_ = null; |
| 20 }; |
| 21 |
| 22 Output.prototype = { |
| 23 /** |
| 24 * Handles output of the given range. |
| 25 */ |
| 26 output: function(range) { |
| 27 var out = {}; |
| 28 if (range.isSubNode()) |
| 29 out = this.subNode_(range); |
| 30 else |
| 31 out = this.node_(range); |
| 32 |
| 33 cvox.ChromeVox.tts.speak(out.text, cvox.QueueMode.FLUSH); |
| 34 cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(out.text)); |
| 35 chrome.accessibilityPrivate.setFocusRing(out.locations); |
| 36 |
| 37 this.prevRange_ = range; |
| 38 }, |
| 39 |
| 40 /** |
| 41 * @param {!cursors.Range} range |
| 42 * @return {{text: string, locations: !Array.<Object>}} |
| 43 * @private |
| 44 */ |
| 45 node_: function(range) { |
| 46 // Walk the range and collect descriptions. |
| 47 var out = {text: '', locations: []}; |
| 48 var cursor = range.getStart(); |
| 49 while (cursor.getNode() != range.getEnd().getNode()) { |
| 50 out.text += this.getCursorDesc_(cursor); |
| 51 out.locations.push(cursor.getNode().location); |
| 52 cursor = cursor.move(cursors.Unit.NODE, |
| 53 cursors.Movement.DIRECTIONAL, |
| 54 AutomationUtil.Dir.FORWARD); |
| 55 } |
| 56 out.text += this.getCursorDesc_(range.getEnd()); |
| 57 out.locations.push(range.getEnd().getNode().location); |
| 58 return out; |
| 59 }, |
| 60 |
| 61 /** |
| 62 * @param {!cursors.Range} range |
| 63 * @return {{text: string, locations: !Array.<Object>}} |
| 64 * @private |
| 65 */ |
| 66 subNode_: function(range) { |
| 67 // TODO(dtseng): Need a way to select subnode ranges (or compute their |
| 68 // rects). |
| 69 var out = {text: '', locations: []}; |
| 70 var startIndex = range.getStart().getIndex(); |
| 71 var endIndex = range.getEnd().getIndex(); |
| 72 if (startIndex === endIndex) |
| 73 endIndex++; |
| 74 |
| 75 out.text = range.getStart().getText().substring(startIndex, endIndex); |
| 76 |
| 77 return out; |
| 78 }, |
| 79 |
| 80 // TODO(dtseng): This is just placeholder logic for generating descriptions |
| 81 // pending further design discussion. |
| 82 /** |
| 83 * @param {!cursors.Cursor} cursor |
| 84 * @return {string} |
| 85 * @private |
| 86 */ |
| 87 getCursorDesc_: function(cursor) { |
| 88 var node = cursor.getNode(); |
| 89 var container = node; |
| 90 while (container && |
| 91 (container.role == chrome.automation.RoleType.inlineTextBox || |
| 92 container.role == chrome.automation.RoleType.staticText)) |
| 93 container = container.parent(); |
| 94 |
| 95 var role = container ? container.role : node.role; |
| 96 return [node.attributes.name, node.attributes.value, role].join(', '); |
| 97 } |
| 98 }; |
OLD | NEW |