| Index: chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js
|
| diff --git a/chrome/browser/resources/chromeos/chromevox/common/editable_text.js b/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js
|
| similarity index 52%
|
| copy from chrome/browser/resources/chromeos/chromevox/common/editable_text.js
|
| copy to chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js
|
| index 54312e0eb0e761eeafca49a99e82b91c7d1a34e5..d7d7bd47dac7443e9196c1706b4d6341be3c4ba0 100644
|
| --- a/chrome/browser/resources/chromeos/chromevox/common/editable_text.js
|
| +++ b/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js
|
| @@ -1,43 +1,26 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Copyright 2015 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.ChromeVoxEditableContentEditable');
|
| -goog.provide('cvox.ChromeVoxEditableHTMLInput');
|
| -goog.provide('cvox.ChromeVoxEditableTextArea');
|
| goog.provide('cvox.ChromeVoxEditableTextBase');
|
| goog.provide('cvox.TextChangeEvent');
|
| -goog.provide('cvox.TextHandlerInterface');
|
| goog.provide('cvox.TypingEcho');
|
|
|
| -
|
| -goog.require('cvox.BrailleTextHandler');
|
| -goog.require('cvox.ContentEditableExtractor');
|
| -goog.require('cvox.DomUtil');
|
| -goog.require('cvox.EditableTextAreaShadow');
|
| +goog.require('cvox.ChromeVox');
|
| goog.require('cvox.TtsInterface');
|
| goog.require('goog.i18n.MessageFormat');
|
|
|
| +
|
| /**
|
| - * @fileoverview Gives the user spoken feedback as they type, select text,
|
| - * and move the cursor in editable text controls, including multiline
|
| - * controls.
|
| - *
|
| - * The majority of the code is in ChromeVoxEditableTextBase, a generalized
|
| - * class that takes the current state in the form of a text string, a
|
| - * cursor start location and a cursor end location, and calls a speak
|
| - * method with the resulting text to be spoken. If the control is multiline,
|
| - * information about line breaks (including automatic ones) is also needed.
|
| - *
|
| - * Two subclasses, ChromeVoxEditableHTMLInput and
|
| - * ChromeVoxEditableTextArea, take a HTML input (type=text) or HTML
|
| - * textarea node (respectively) in the constructor, and automatically
|
| - * handle retrieving the current state of the control, including
|
| - * computing line break information for a textarea using an offscreen
|
| - * shadow object. It is still the responsibility of the user of this
|
| - * class to trap key and focus events and call this class's update
|
| - * method.
|
| + * @fileoverview Generalized logic for providing spoken feedback when editing
|
| + * text fields, both single and multiline fields.
|
| *
|
| + * {@code ChromeVoxEditableTextBase} is a generalized class that takes the
|
| + * current state in the form of a text string, a cursor start location and a
|
| + * cursor end location, and calls a speak method with the resulting text to
|
| + * be spoken. This class can be used directly for single line fields or
|
| + * extended to override methods that extract lines for multiline fields
|
| + * or to provide other customizations.
|
| */
|
|
|
|
|
| @@ -106,20 +89,6 @@ cvox.TypingEcho.shouldSpeakChar = function(typingEcho) {
|
|
|
|
|
| /**
|
| - * An interface for being notified when the text changes.
|
| - * @interface
|
| - */
|
| -cvox.TextHandlerInterface = function() {};
|
| -
|
| -
|
| -/**
|
| - * Called when text changes.
|
| - * @param {cvox.TextChangeEvent} evt The text change event.
|
| - */
|
| -cvox.TextHandlerInterface.prototype.changed = function(evt) {};
|
| -
|
| -
|
| -/**
|
| * A class representing an abstracted editable text control.
|
| * @param {string} value The string value of the editable text control.
|
| * @param {number} start The 0-based start cursor/selection index.
|
| @@ -172,12 +141,14 @@ cvox.ChromeVoxEditableTextBase = function(value, start, end, isPassword, tts) {
|
| this.multiline = false;
|
|
|
| /**
|
| - * An optional handler for braille output.
|
| - * @type {cvox.BrailleTextHandler|undefined}
|
| - * @private
|
| + * Whether or not the last update to the text and selection was described.
|
| + *
|
| + * Some consumers of this flag like |ChromeVoxEventWatcher| depend on and
|
| + * react to when this flag is false by generating alternative feedback.
|
| + * @type {boolean}
|
| */
|
| - this.brailleHandler_ = cvox.ChromeVox.braille ?
|
| - new cvox.BrailleTextHandler(cvox.ChromeVox.braille) : undefined;
|
| + this.lastChangeDescribed = false;
|
| +
|
| };
|
|
|
|
|
| @@ -234,24 +205,6 @@ cvox.ChromeVoxEditableTextBase.prototype.maxShortPhraseLen = 60;
|
|
|
|
|
| /**
|
| - * Whether or not the text control is a password.
|
| - *
|
| - * @type {boolean}
|
| - */
|
| -cvox.ChromeVoxEditableTextBase.prototype.isPassword = false;
|
| -
|
| -
|
| -/**
|
| - * Whether or not the last update to the text and selection was described.
|
| - *
|
| - * Some consumers of this flag like |ChromeVoxEventWatcher| depend on and
|
| - * react to when this flag is false by generating alternative feedback.
|
| - * @type {boolean}
|
| - */
|
| -cvox.ChromeVoxEditableTextBase.prototype.lastChangeDescribed = false;
|
| -
|
| -
|
| -/**
|
| * Get the line number corresponding to a particular index.
|
| * Default implementation that can be overridden by subclasses.
|
| * @param {number} index The 0-based character index.
|
| @@ -339,11 +292,6 @@ cvox.ChromeVoxEditableTextBase.prototype.shouldDescribeChange = function(evt) {
|
| */
|
| cvox.ChromeVoxEditableTextBase.prototype.speak =
|
| function(str, opt_triggeredByUser, opt_personality) {
|
| - // If there is a node associated with the editable text object,
|
| - // make sure that node has focus before speaking it.
|
| - if (this.node && (document.activeElement != this.node)) {
|
| - return;
|
| - }
|
| var queueMode = cvox.QueueMode.QUEUE;
|
| if (opt_triggeredByUser === true) {
|
| queueMode = cvox.QueueMode.FLUSH;
|
| @@ -374,36 +322,10 @@ cvox.ChromeVoxEditableTextBase.prototype.changed = function(evt) {
|
| this.value = evt.value;
|
| this.start = evt.start;
|
| this.end = evt.end;
|
| -
|
| - this.brailleCurrentLine_();
|
| };
|
|
|
|
|
| /**
|
| - * Shows the current line on the braille display.
|
| - * @private
|
| - */
|
| -cvox.ChromeVoxEditableTextBase.prototype.brailleCurrentLine_ = function() {
|
| - if (this.brailleHandler_) {
|
| - var lineIndex = this.getLineIndex(this.start);
|
| - var line = this.getLine(lineIndex);
|
| - // Collapsable whitespace inside the contenteditable is represented
|
| - // as non-breaking spaces. This confuses braille input (which relies on
|
| - // the text being added to be the same as the text in the input field).
|
| - // Since the non-breaking spaces are just an artifact of how
|
| - // contenteditable is implemented, normalize to normal spaces instead.
|
| - if (this instanceof cvox.ChromeVoxEditableContentEditable) {
|
| - line = line.replace(/\u00A0/g, ' ');
|
| - }
|
| - var lineStart = this.getLineStart(lineIndex);
|
| - var start = this.start - lineStart;
|
| - var end = Math.min(this.end - lineStart, line.length);
|
| - this.brailleHandler_.changed(line, start, end, this.multiline, this.node,
|
| - lineStart);
|
| - }
|
| -};
|
| -
|
| -/**
|
| * Describe a change in the selection or cursor position when the text
|
| * stays the same.
|
| * @param {cvox.TextChangeEvent} evt The text change event.
|
| @@ -787,567 +709,3 @@ cvox.ChromeVoxEditableTextBase.prototype.moveCursorToPreviousParagraph =
|
|
|
|
|
| /******************************************/
|
| -
|
| -
|
| -/**
|
| - * A subclass of ChromeVoxEditableTextBase a text element that's part of
|
| - * the webpage DOM. Contains common code shared by both EditableHTMLInput
|
| - * and EditableTextArea, but that might not apply to a non-DOM text box.
|
| - * @param {Element} node A DOM node which allows text input.
|
| - * @param {string} value The string value of the editable text control.
|
| - * @param {number} start The 0-based start cursor/selection index.
|
| - * @param {number} end The 0-based end cursor/selection index.
|
| - * @param {boolean} isPassword Whether the text control if a password field.
|
| - * @param {cvox.TtsInterface} tts A TTS object.
|
| - * @extends {cvox.ChromeVoxEditableTextBase}
|
| - * @constructor
|
| - */
|
| -cvox.ChromeVoxEditableElement = function(node, value, start, end, isPassword,
|
| - tts) {
|
| - goog.base(this, value, start, end, isPassword, tts);
|
| -
|
| - /**
|
| - * The DOM node which allows text input.
|
| - * @type {Element}
|
| - * @protected
|
| - */
|
| - this.node = node;
|
| -
|
| - /**
|
| - * True if the description was just spoken.
|
| - * @type {boolean}
|
| - * @private
|
| - */
|
| - this.justSpokeDescription_ = false;
|
| -};
|
| -goog.inherits(cvox.ChromeVoxEditableElement,
|
| - cvox.ChromeVoxEditableTextBase);
|
| -
|
| -
|
| -/**
|
| - * Update the state of the text and selection and describe any changes as
|
| - * appropriate.
|
| - *
|
| - * @param {cvox.TextChangeEvent} evt The text change event.
|
| - */
|
| -cvox.ChromeVoxEditableElement.prototype.changed = function(evt) {
|
| - // Ignore changes to the cursor and selection if they happen immediately
|
| - // after the description was just spoken. This avoid double-speaking when,
|
| - // for example, a text field is focused and then a moment later the
|
| - // contents are selected. If the value changes, though, this change will
|
| - // not be ignored.
|
| - if (this.justSpokeDescription_ && this.value == evt.value) {
|
| - this.value = evt.value;
|
| - this.start = evt.start;
|
| - this.end = evt.end;
|
| - this.justSpokeDescription_ = false;
|
| - }
|
| - goog.base(this, 'changed', evt);
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableElement.prototype.moveCursorToNextCharacter = function() {
|
| - var node = this.node;
|
| - node.selectionEnd++;
|
| - node.selectionStart = node.selectionEnd;
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableElement.prototype.moveCursorToPreviousCharacter =
|
| - function() {
|
| - var node = this.node;
|
| - node.selectionStart--;
|
| - node.selectionEnd = node.selectionStart;
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableElement.prototype.moveCursorToNextWord = function() {
|
| - var node = this.node;
|
| - var length = node.value.length;
|
| - var re = /\W+/gm;
|
| - var substring = node.value.substring(node.selectionEnd);
|
| - var match = re.exec(substring);
|
| - if (match !== null && match.index == 0) {
|
| - // Ignore word-breaking sequences right next to the cursor.
|
| - match = re.exec(substring);
|
| - }
|
| - var index = (match === null) ? length : match.index + node.selectionEnd;
|
| - node.selectionStart = node.selectionEnd = index;
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableElement.prototype.moveCursorToPreviousWord = function() {
|
| - var node = this.node;
|
| - var length = node.value.length;
|
| - var re = /\W+/gm;
|
| - var substring = node.value.substring(0, node.selectionStart);
|
| - var index = 0;
|
| - while (re.exec(substring) !== null) {
|
| - if (re.lastIndex < node.selectionStart) {
|
| - index = re.lastIndex;
|
| - }
|
| - }
|
| - node.selectionStart = node.selectionEnd = index;
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableElement.prototype.moveCursorToNextParagraph =
|
| - function() {
|
| - var node = this.node;
|
| - var length = node.value.length;
|
| - var index = node.selectionEnd >= length ? length :
|
| - node.value.indexOf('\n', node.selectionEnd);
|
| - if (index < 0) {
|
| - index = length;
|
| - }
|
| - node.selectionStart = node.selectionEnd = index + 1;
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableElement.prototype.moveCursorToPreviousParagraph =
|
| - function() {
|
| - var node = this.node;
|
| - var index = node.selectionStart <= 0 ? 0 :
|
| - node.value.lastIndexOf('\n', node.selectionStart - 2) + 1;
|
| - if (index < 0) {
|
| - index = 0;
|
| - }
|
| - node.selectionStart = node.selectionEnd = index;
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/******************************************/
|
| -
|
| -
|
| -/**
|
| - * A subclass of ChromeVoxEditableElement for an HTMLInputElement.
|
| - * @param {HTMLInputElement} node The HTMLInputElement node.
|
| - * @param {cvox.TtsInterface} tts A TTS object.
|
| - * @extends {cvox.ChromeVoxEditableElement}
|
| - * @implements {cvox.TextHandlerInterface}
|
| - * @constructor
|
| - */
|
| -cvox.ChromeVoxEditableHTMLInput = function(node, tts) {
|
| - this.node = node;
|
| - this.setup();
|
| - goog.base(this,
|
| - node,
|
| - node.value,
|
| - node.selectionStart,
|
| - node.selectionEnd,
|
| - node.type === 'password',
|
| - tts);
|
| -};
|
| -goog.inherits(cvox.ChromeVoxEditableHTMLInput,
|
| - cvox.ChromeVoxEditableElement);
|
| -
|
| -
|
| -/**
|
| - * Performs setup for this input node.
|
| - * This accounts for exception-throwing behavior introduced by crbug.com/324360.
|
| - * @override
|
| - */
|
| -cvox.ChromeVoxEditableHTMLInput.prototype.setup = function() {
|
| - if (!this.node) {
|
| - return;
|
| - }
|
| - if (!cvox.DomUtil.doesInputSupportSelection(this.node)) {
|
| - this.originalType = this.node.type;
|
| - this.node.type = 'text';
|
| - }
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Performs teardown for this input node.
|
| - * This accounts for exception-throwing behavior introduced by crbug.com/324360.
|
| - * @override
|
| - */
|
| -cvox.ChromeVoxEditableHTMLInput.prototype.teardown = function() {
|
| - if (this.node && this.originalType) {
|
| - this.node.type = this.originalType;
|
| - }
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Update the state of the text and selection and describe any changes as
|
| - * appropriate.
|
| - *
|
| - * @param {boolean} triggeredByUser True if this was triggered by a user action.
|
| - */
|
| -cvox.ChromeVoxEditableHTMLInput.prototype.update = function(triggeredByUser) {
|
| - var newValue = this.node.value;
|
| - var textChangeEvent = new cvox.TextChangeEvent(newValue,
|
| - this.node.selectionStart,
|
| - this.node.selectionEnd,
|
| - triggeredByUser);
|
| - this.changed(textChangeEvent);
|
| -};
|
| -
|
| -
|
| -/******************************************/
|
| -
|
| -
|
| -/**
|
| - * A subclass of ChromeVoxEditableElement for an HTMLTextAreaElement.
|
| - * @param {HTMLTextAreaElement} node The HTMLTextAreaElement node.
|
| - * @param {cvox.TtsInterface} tts A TTS object.
|
| - * @extends {cvox.ChromeVoxEditableElement}
|
| - * @implements {cvox.TextHandlerInterface}
|
| - * @constructor
|
| - */
|
| -cvox.ChromeVoxEditableTextArea = function(node, tts) {
|
| - goog.base(this, node, node.value, node.selectionStart, node.selectionEnd,
|
| - false /* isPassword */, tts);
|
| - this.multiline = true;
|
| -
|
| - /**
|
| - * True if the shadow is up-to-date with the current value of this text area.
|
| - * @type {boolean}
|
| - * @private
|
| - */
|
| - this.shadowIsCurrent_ = false;
|
| -};
|
| -goog.inherits(cvox.ChromeVoxEditableTextArea,
|
| - cvox.ChromeVoxEditableElement);
|
| -
|
| -
|
| -/**
|
| - * An offscreen div used to compute the line numbers. A single div is
|
| - * shared by all instances of the class.
|
| - * @type {!cvox.EditableTextAreaShadow|undefined}
|
| - * @private
|
| - */
|
| -cvox.ChromeVoxEditableTextArea.shadow_;
|
| -
|
| -
|
| -/**
|
| - * Update the state of the text and selection and describe any changes as
|
| - * appropriate.
|
| - *
|
| - * @param {boolean} triggeredByUser True if this was triggered by a user action.
|
| - */
|
| -cvox.ChromeVoxEditableTextArea.prototype.update = function(triggeredByUser) {
|
| - if (this.node.value != this.value) {
|
| - this.shadowIsCurrent_ = false;
|
| - }
|
| - var textChangeEvent = new cvox.TextChangeEvent(this.node.value,
|
| - this.node.selectionStart, this.node.selectionEnd, triggeredByUser);
|
| - this.changed(textChangeEvent);
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Get the line number corresponding to a particular index.
|
| - * @param {number} index The 0-based character index.
|
| - * @return {number} The 0-based line number corresponding to that character.
|
| - */
|
| -cvox.ChromeVoxEditableTextArea.prototype.getLineIndex = function(index) {
|
| - return this.getShadow().getLineIndex(index);
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Get the start character index of a line.
|
| - * @param {number} index The 0-based line index.
|
| - * @return {number} The 0-based index of the first character in this line.
|
| - */
|
| -cvox.ChromeVoxEditableTextArea.prototype.getLineStart = function(index) {
|
| - return this.getShadow().getLineStart(index);
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Get the end character index of a line.
|
| - * @param {number} index The 0-based line index.
|
| - * @return {number} The 0-based index of the end of this line.
|
| - */
|
| -cvox.ChromeVoxEditableTextArea.prototype.getLineEnd = function(index) {
|
| - return this.getShadow().getLineEnd(index);
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Update the shadow object, an offscreen div used to compute line numbers.
|
| - * @return {!cvox.EditableTextAreaShadow} The shadow object.
|
| - */
|
| -cvox.ChromeVoxEditableTextArea.prototype.getShadow = function() {
|
| - var shadow = cvox.ChromeVoxEditableTextArea.shadow_;
|
| - if (!shadow) {
|
| - shadow = cvox.ChromeVoxEditableTextArea.shadow_ =
|
| - new cvox.EditableTextAreaShadow();
|
| - }
|
| - if (!this.shadowIsCurrent_) {
|
| - shadow.update(this.node);
|
| - this.shadowIsCurrent_ = true;
|
| - }
|
| - return shadow;
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableTextArea.prototype.moveCursorToNextLine = function() {
|
| - var node = this.node;
|
| - var length = node.value.length;
|
| - if (node.selectionEnd >= length) {
|
| - return false;
|
| - }
|
| - var shadow = this.getShadow();
|
| - var lineIndex = shadow.getLineIndex(node.selectionEnd);
|
| - var lineStart = shadow.getLineStart(lineIndex);
|
| - var offset = node.selectionEnd - lineStart;
|
| - var lastLine = (length == 0) ? 0 : shadow.getLineIndex(length - 1);
|
| - var newCursorPosition = (lineIndex >= lastLine) ? length :
|
| - Math.min(shadow.getLineStart(lineIndex + 1) + offset,
|
| - shadow.getLineEnd(lineIndex + 1));
|
| - node.selectionStart = node.selectionEnd = newCursorPosition;
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableTextArea.prototype.moveCursorToPreviousLine = function() {
|
| - var node = this.node;
|
| - if (node.selectionStart <= 0) {
|
| - return false;
|
| - }
|
| - var shadow = this.getShadow();
|
| - var lineIndex = shadow.getLineIndex(node.selectionStart);
|
| - var lineStart = shadow.getLineStart(lineIndex);
|
| - var offset = node.selectionStart - lineStart;
|
| - var newCursorPosition = (lineIndex <= 0) ? 0 :
|
| - Math.min(shadow.getLineStart(lineIndex - 1) + offset,
|
| - shadow.getLineEnd(lineIndex - 1));
|
| - node.selectionStart = node.selectionEnd = newCursorPosition;
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/******************************************/
|
| -
|
| -
|
| -/**
|
| - * A subclass of ChromeVoxEditableElement for elements that are contentEditable.
|
| - * This is also used for a region of HTML with the ARIA role of "textbox",
|
| - * so that an author can create a pure-JavaScript editable text object - this
|
| - * will work the same as contentEditable as long as the DOM selection is
|
| - * updated properly within the textbox when it has focus.
|
| - * @param {Element} node The root contentEditable node.
|
| - * @param {cvox.TtsInterface} tts A TTS object.
|
| - * @extends {cvox.ChromeVoxEditableElement}
|
| - * @implements {cvox.TextHandlerInterface}
|
| - * @constructor
|
| - */
|
| -cvox.ChromeVoxEditableContentEditable = function(node, tts) {
|
| - goog.base(this, node, '', 0, 0, false /* isPassword */, tts);
|
| -
|
| -
|
| - /**
|
| - * True if the ContentEditableExtractor is current with this field's data.
|
| - * @type {boolean}
|
| - * @private
|
| - */
|
| - this.extractorIsCurrent_ = false;
|
| -
|
| - var extractor = this.getExtractor();
|
| - this.value = extractor.getText();
|
| - this.start = extractor.getStartIndex();
|
| - this.end = extractor.getEndIndex();
|
| - this.multiline = true;
|
| -};
|
| -goog.inherits(cvox.ChromeVoxEditableContentEditable,
|
| - cvox.ChromeVoxEditableElement);
|
| -
|
| -/**
|
| - * A helper used to compute the line numbers. A single object is
|
| - * shared by all instances of the class.
|
| - * @type {!cvox.ContentEditableExtractor|undefined}
|
| - * @private
|
| - */
|
| -cvox.ChromeVoxEditableContentEditable.extractor_;
|
| -
|
| -
|
| -/**
|
| - * Update the state of the text and selection and describe any changes as
|
| - * appropriate.
|
| - *
|
| - * @param {boolean} triggeredByUser True if this was triggered by a user action.
|
| - */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.update =
|
| - function(triggeredByUser) {
|
| - this.extractorIsCurrent_ = false;
|
| - var textChangeEvent = new cvox.TextChangeEvent(
|
| - this.getExtractor().getText(),
|
| - this.getExtractor().getStartIndex(),
|
| - this.getExtractor().getEndIndex(),
|
| - triggeredByUser);
|
| - this.changed(textChangeEvent);
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Get the line number corresponding to a particular index.
|
| - * @param {number} index The 0-based character index.
|
| - * @return {number} The 0-based line number corresponding to that character.
|
| - */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.getLineIndex = function(index) {
|
| - return this.getExtractor().getLineIndex(index);
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Get the start character index of a line.
|
| - * @param {number} index The 0-based line index.
|
| - * @return {number} The 0-based index of the first character in this line.
|
| - */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.getLineStart = function(index) {
|
| - return this.getExtractor().getLineStart(index);
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Get the end character index of a line.
|
| - * @param {number} index The 0-based line index.
|
| - * @return {number} The 0-based index of the end of this line.
|
| - */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.getLineEnd = function(index) {
|
| - return this.getExtractor().getLineEnd(index);
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Update the extractor object, an offscreen div used to compute line numbers.
|
| - * @return {!cvox.ContentEditableExtractor} The extractor object.
|
| - */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.getExtractor = function() {
|
| - var extractor = cvox.ChromeVoxEditableContentEditable.extractor_;
|
| - if (!extractor) {
|
| - extractor = cvox.ChromeVoxEditableContentEditable.extractor_ =
|
| - new cvox.ContentEditableExtractor();
|
| - }
|
| - if (!this.extractorIsCurrent_) {
|
| - extractor.update(this.node);
|
| - this.extractorIsCurrent_ = true;
|
| - }
|
| - return extractor;
|
| -};
|
| -
|
| -
|
| -/**
|
| - * @override
|
| - */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.changed =
|
| - function(evt) {
|
| - if (!evt.triggeredByUser) {
|
| - return;
|
| - }
|
| - // Take over here if we can't describe a change; assume it's a blank line.
|
| - if (!this.shouldDescribeChange(evt)) {
|
| - this.speak(cvox.ChromeVox.msgs.getMsg('text_box_blank'), true);
|
| - if (this.brailleHandler_) {
|
| - this.brailleHandler_.changed('' /*line*/, 0 /*start*/, 0 /*end*/,
|
| - true /*multiline*/, null /*element*/,
|
| - evt.start /*lineStart*/);
|
| - }
|
| - } else {
|
| - goog.base(this, 'changed', evt);
|
| - }
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.moveCursorToNextCharacter =
|
| - function() {
|
| - window.getSelection().modify('move', 'forward', 'character');
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.moveCursorToPreviousCharacter =
|
| - function() {
|
| - window.getSelection().modify('move', 'backward', 'character');
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.moveCursorToNextParagraph =
|
| - function() {
|
| - window.getSelection().modify('move', 'forward', 'paragraph');
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -/** @override */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.moveCursorToPreviousParagraph =
|
| - function() {
|
| - window.getSelection().modify('move', 'backward', 'paragraph');
|
| - cvox.ChromeVoxEventWatcher.handleTextChanged(true);
|
| - return true;
|
| -};
|
| -
|
| -
|
| -/**
|
| - * @override
|
| - */
|
| -cvox.ChromeVoxEditableContentEditable.prototype.shouldDescribeChange =
|
| - function(evt) {
|
| - var sel = window.getSelection();
|
| - var cursor = new cvox.Cursor(sel.baseNode, sel.baseOffset, '');
|
| -
|
| - // This is a very specific work around because of our buggy content editable
|
| - // support. Blank new lines are not captured in the line indexing data
|
| - // structures.
|
| - // Scenario: given a piece of text like:
|
| - //
|
| - // Some Title
|
| - //
|
| - // Description
|
| - // Footer
|
| - //
|
| - // The new lines after Title are not traversed to by TraverseUtil. A root fix
|
| - // would make changes there. However, considering the fickle nature of that
|
| - // code, we specifically detect for new lines here.
|
| - if (Math.abs(this.start - evt.start) != 1 &&
|
| - this.start == this.end &&
|
| - evt.start == evt.end &&
|
| - sel.baseNode == sel.extentNode &&
|
| - sel.baseOffset == sel.extentOffset &&
|
| - sel.baseNode.nodeType == Node.ELEMENT_NODE &&
|
| - sel.baseNode.querySelector('BR') &&
|
| - cvox.TraverseUtil.forwardsChar(cursor, [], [])) {
|
| - // This case detects if the range selection surrounds a new line,
|
| - // but there is still content after the new line (like the example
|
| - // above after "Title"). In these cases, we "pretend" we're the
|
| - // last character so we speak "blank".
|
| - return false;
|
| - }
|
| -
|
| - // Otherwise, we should never speak "blank" no matter what (even if
|
| - // we're at the end of a content editable).
|
| - return true;
|
| -};
|
|
|