Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview Processes events related to editing text and emits the | 6 * @fileoverview Processes events related to editing text and emits the |
| 7 * appropriate spoken and braille feedback. | 7 * appropriate spoken and braille feedback. |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 goog.provide('editing.TextEditHandler'); | 10 goog.provide('editing.TextEditHandler'); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 * @extends {cvox.ChromeVoxEditableTextBase} | 107 * @extends {cvox.ChromeVoxEditableTextBase} |
| 108 */ | 108 */ |
| 109 function AutomationEditableText(node) { | 109 function AutomationEditableText(node) { |
| 110 if (!node.state.editable) | 110 if (!node.state.editable) |
| 111 throw Error('Node must have editable state set to true.'); | 111 throw Error('Node must have editable state set to true.'); |
| 112 var start = node.textSelStart; | 112 var start = node.textSelStart; |
| 113 var end = node.textSelEnd; | 113 var end = node.textSelEnd; |
| 114 cvox.ChromeVoxEditableTextBase.call( | 114 cvox.ChromeVoxEditableTextBase.call( |
| 115 this, node.value || '', Math.min(start, end), Math.max(start, end), | 115 this, node.value || '', Math.min(start, end), Math.max(start, end), |
| 116 node.state[StateType.PROTECTED] /**password*/, cvox.ChromeVox.tts); | 116 node.state[StateType.PROTECTED] /**password*/, cvox.ChromeVox.tts); |
| 117 /** @override */ | |
| 118 this.multiline = node.state[StateType.MULTILINE] || false; | |
| 119 /** @type {!AutomationNode} @private */ | 117 /** @type {!AutomationNode} @private */ |
| 120 this.node_ = node; | 118 this.node_ = node; |
| 121 /** @type {Array<number>} @private */ | |
| 122 this.lineBreaks_ = []; | |
| 123 } | 119 } |
| 124 | 120 |
| 125 AutomationEditableText.prototype = { | 121 AutomationEditableText.prototype = { |
| 126 __proto__: cvox.ChromeVoxEditableTextBase.prototype, | 122 __proto__: cvox.ChromeVoxEditableTextBase.prototype, |
| 127 | 123 |
| 128 /** | 124 /** |
| 129 * Called when the text field has been updated. | 125 * Called when the text field has been updated. |
| 130 */ | 126 */ |
| 131 onUpdate: function() { | 127 onUpdate: function() { |
| 132 var newValue = this.node_.value || ''; | 128 var newValue = this.node_.value || ''; |
| 133 | 129 |
| 134 if (this.value != newValue) | |
| 135 this.lineBreaks_ = []; | |
| 136 | |
| 137 var textChangeEvent = new cvox.TextChangeEvent( | 130 var textChangeEvent = new cvox.TextChangeEvent( |
| 138 newValue, this.node_.textSelStart || 0, this.node_.textSelEnd || 0, | 131 newValue, this.node_.textSelStart || 0, this.node_.textSelEnd || 0, |
| 139 true /* triggered by user */); | 132 true /* triggered by user */); |
| 140 this.changed(textChangeEvent); | 133 this.changed(textChangeEvent); |
| 141 this.outputBraille_(); | 134 this.outputBraille_(); |
| 142 }, | 135 }, |
| 143 | 136 |
| 144 /** @override */ | 137 /** @override */ |
| 145 getLineIndex: function(charIndex) { | 138 getLineIndex: function(charIndex) { |
| 146 if (!this.multiline) | 139 var breaks = this.node_.lineBreaks || []; |
| 140 if (!breaks.length) | |
| 147 return 0; | 141 return 0; |
| 148 var breaks = this.node_.lineBreaks || []; | |
| 149 var index = 0; | 142 var index = 0; |
| 150 while (index < breaks.length && breaks[index] <= charIndex) | 143 while (index < breaks.length && breaks[index] <= charIndex) |
| 151 ++index; | 144 ++index; |
| 152 return index; | 145 return index; |
| 153 }, | 146 }, |
| 154 | 147 |
| 155 /** @override */ | 148 /** @override */ |
| 156 getLineStart: function(lineIndex) { | 149 getLineStart: function(lineIndex) { |
| 157 if (!this.multiline || lineIndex == 0) | 150 if (lineIndex == 0) |
| 158 return 0; | 151 return 0; |
| 159 var breaks = this.getLineBreaks_(); | 152 var breaks = this.getLineBreaks_(); |
| 153 if (breaks.length < 1) | |
| 154 return 0; | |
| 160 return breaks[lineIndex - 1] || this.node_.value.length; | 155 return breaks[lineIndex - 1] || this.node_.value.length; |
| 161 }, | 156 }, |
| 162 | 157 |
| 163 /** @override */ | 158 /** @override */ |
| 164 getLineEnd: function(lineIndex) { | 159 getLineEnd: function(lineIndex) { |
| 165 var breaks = this.getLineBreaks_(); | 160 var breaks = this.getLineBreaks_(); |
| 166 var value = this.node_.value; | 161 var value = this.node_.value; |
| 167 if (lineIndex >= breaks.length) | 162 if (lineIndex >= breaks.length) |
| 168 return value.length; | 163 return value.length; |
| 169 return breaks[lineIndex] - 1; | 164 return breaks[lineIndex] - 1; |
| 170 }, | 165 }, |
| 171 | 166 |
| 172 /** | 167 /** |
| 173 * @return {Array<number>} | 168 * @return {Array<number>} |
| 174 * @private | 169 * @private |
| 175 */ | 170 */ |
| 176 getLineBreaks_: function() { | 171 getLineBreaks_: function() { |
| 177 // node.lineBreaks is undefined when the multiline field has no line | 172 // node.lineBreaks is undefined when the multiline field has no line |
| 178 // breaks. | 173 // breaks. |
| 179 return this.node_.lineBreaks || []; | 174 return this.node_.lineBreaks || []; |
| 180 }, | 175 }, |
| 181 | 176 |
| 182 /** @private */ | 177 /** @private */ |
| 183 outputBraille_: function() { | 178 outputBraille_: function() { |
| 184 var isFirstLine = false; // First line in a multiline field. | 179 var isFirstLine = false; // First line in a multiline field. |
| 185 var output = new Output(); | 180 var output = new Output(); |
| 186 var range; | 181 var range; |
| 187 if (this.multiline) { | 182 if (this.getLineBreaks_().length) { |
|
David Tseng
2017/06/27 18:41:14
This isn't equivalent. Whether something is not mu
| |
| 188 var lineIndex = this.getLineIndex(this.start); | 183 var lineIndex = this.getLineIndex(this.start); |
| 189 if (lineIndex == 0) { | 184 if (lineIndex == 0) { |
| 190 isFirstLine = true; | 185 isFirstLine = true; |
| 191 output.formatForBraille('$name', this.node_); | 186 output.formatForBraille('$name', this.node_); |
| 192 } | 187 } |
| 193 range = new Range( | 188 range = new Range( |
| 194 new Cursor(this.node_, this.getLineStart(lineIndex)), | 189 new Cursor(this.node_, this.getLineStart(lineIndex)), |
| 195 new Cursor(this.node_, this.getLineEnd(lineIndex))); | 190 new Cursor(this.node_, this.getLineEnd(lineIndex))); |
| 196 } else { | 191 } else { |
| 197 range = Range.fromNode(this.node_); | 192 range = Range.fromNode(this.node_); |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 766 * @return {boolean} | 761 * @return {boolean} |
| 767 */ | 762 */ |
| 768 isSameLineAndSelection: function(otherLine) { | 763 isSameLineAndSelection: function(otherLine) { |
| 769 return this.isSameLine(otherLine) && | 764 return this.isSameLine(otherLine) && |
| 770 this.startOffset == otherLine.startOffset && | 765 this.startOffset == otherLine.startOffset && |
| 771 this.endOffset == otherLine.endOffset; | 766 this.endOffset == otherLine.endOffset; |
| 772 } | 767 } |
| 773 }; | 768 }; |
| 774 | 769 |
| 775 }); | 770 }); |
| OLD | NEW |