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 goog.provide('cvox.ChromeVoxEditableTextBase'); | 5 goog.provide('cvox.ChromeVoxEditableTextBase'); |
6 goog.provide('cvox.TextChangeEvent'); | 6 goog.provide('cvox.TextChangeEvent'); |
7 goog.provide('cvox.TypingEcho'); | 7 goog.provide('cvox.TypingEcho'); |
8 | 8 |
9 goog.require('cvox.AbstractTts'); | 9 goog.require('cvox.AbstractTts'); |
10 goog.require('cvox.ChromeVox'); | 10 goog.require('cvox.ChromeVox'); |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 * stays the same. | 331 * stays the same. |
332 * @param {cvox.TextChangeEvent} evt The text change event. | 332 * @param {cvox.TextChangeEvent} evt The text change event. |
333 */ | 333 */ |
334 cvox.ChromeVoxEditableTextBase.prototype.describeSelectionChanged = | 334 cvox.ChromeVoxEditableTextBase.prototype.describeSelectionChanged = |
335 function(evt) { | 335 function(evt) { |
336 // TODO(deboer): Factor this into two function: | 336 // TODO(deboer): Factor this into two function: |
337 // - one to determine the selection event | 337 // - one to determine the selection event |
338 // - one to speak | 338 // - one to speak |
339 | 339 |
340 if (this.isPassword) { | 340 if (this.isPassword) { |
341 this.speak((new goog.i18n.MessageFormat(cvox.ChromeVox.msgs.getMsg('dot')) | 341 this.speak((new goog.i18n.MessageFormat(Msgs.getMsg('dot')) |
342 .format({'COUNT': 1})), evt.triggeredByUser); | 342 .format({'COUNT': 1})), evt.triggeredByUser); |
343 return; | 343 return; |
344 } | 344 } |
345 if (evt.start == evt.end) { | 345 if (evt.start == evt.end) { |
346 // It's currently a cursor. | 346 // It's currently a cursor. |
347 if (this.start != this.end) { | 347 if (this.start != this.end) { |
348 // It was previously a selection, so just announce 'unselected'. | 348 // It was previously a selection, so just announce 'unselected'. |
349 this.speak(cvox.ChromeVox.msgs.getMsg('Unselected'), evt.triggeredByUser); | 349 this.speak(Msgs.getMsg('Unselected'), evt.triggeredByUser); |
350 } else if (this.getLineIndex(this.start) != | 350 } else if (this.getLineIndex(this.start) != |
351 this.getLineIndex(evt.start)) { | 351 this.getLineIndex(evt.start)) { |
352 // Moved to a different line; read it. | 352 // Moved to a different line; read it. |
353 var lineValue = this.getLine(this.getLineIndex(evt.start)); | 353 var lineValue = this.getLine(this.getLineIndex(evt.start)); |
354 if (lineValue == '') { | 354 if (lineValue == '') { |
355 lineValue = cvox.ChromeVox.msgs.getMsg('text_box_blank'); | 355 lineValue = Msgs.getMsg('text_box_blank'); |
356 } else if (/^\s+$/.test(lineValue)) { | 356 } else if (/^\s+$/.test(lineValue)) { |
357 lineValue = cvox.ChromeVox.msgs.getMsg('text_box_whitespace'); | 357 lineValue = Msgs.getMsg('text_box_whitespace'); |
358 } | 358 } |
359 this.speak(lineValue, evt.triggeredByUser); | 359 this.speak(lineValue, evt.triggeredByUser); |
360 } else if (this.start == evt.start + 1 || | 360 } else if (this.start == evt.start + 1 || |
361 this.start == evt.start - 1) { | 361 this.start == evt.start - 1) { |
362 // Moved by one character; read it. | 362 // Moved by one character; read it. |
363 if (!cvox.ChromeVoxEditableTextBase.useIBeamCursor) { | 363 if (!cvox.ChromeVoxEditableTextBase.useIBeamCursor) { |
364 if (evt.start == this.value.length) { | 364 if (evt.start == this.value.length) { |
365 if (cvox.ChromeVox.verbosity == cvox.VERBOSITY_VERBOSE) { | 365 if (cvox.ChromeVox.verbosity == cvox.VERBOSITY_VERBOSE) { |
366 this.speak(cvox.ChromeVox.msgs.getMsg('end_of_text_verbose'), | 366 this.speak(Msgs.getMsg('end_of_text_verbose'), |
367 evt.triggeredByUser); | 367 evt.triggeredByUser); |
368 } else { | 368 } else { |
369 this.speak(cvox.ChromeVox.msgs.getMsg('end_of_text_brief'), | 369 this.speak(Msgs.getMsg('end_of_text_brief'), |
370 evt.triggeredByUser); | 370 evt.triggeredByUser); |
371 } | 371 } |
372 } else { | 372 } else { |
373 this.speak(this.value.substr(evt.start, 1), | 373 this.speak(this.value.substr(evt.start, 1), |
374 evt.triggeredByUser, | 374 evt.triggeredByUser, |
375 {'phoneticCharacters': evt.triggeredByUser}); | 375 {'phoneticCharacters': evt.triggeredByUser}); |
376 } | 376 } |
377 } else { | 377 } else { |
378 this.speak(this.value.substr(Math.min(this.start, evt.start), 1), | 378 this.speak(this.value.substr(Math.min(this.start, evt.start), 1), |
379 evt.triggeredByUser, | 379 evt.triggeredByUser, |
380 {'phoneticCharacters': evt.triggeredByUser}); | 380 {'phoneticCharacters': evt.triggeredByUser}); |
381 } | 381 } |
382 } else { | 382 } else { |
383 // Moved by more than one character. Read all characters crossed. | 383 // Moved by more than one character. Read all characters crossed. |
384 this.speak(this.value.substr(Math.min(this.start, evt.start), | 384 this.speak(this.value.substr(Math.min(this.start, evt.start), |
385 Math.abs(this.start - evt.start)), evt.triggeredByUser); | 385 Math.abs(this.start - evt.start)), evt.triggeredByUser); |
386 } | 386 } |
387 } else { | 387 } else { |
388 // It's currently a selection. | 388 // It's currently a selection. |
389 if (this.start + 1 == evt.start && | 389 if (this.start + 1 == evt.start && |
390 this.end == this.value.length && | 390 this.end == this.value.length && |
391 evt.end == this.value.length) { | 391 evt.end == this.value.length) { |
392 // Autocomplete: the user typed one character of autocompleted text. | 392 // Autocomplete: the user typed one character of autocompleted text. |
393 this.speak(this.value.substr(this.start, 1), evt.triggeredByUser); | 393 this.speak(this.value.substr(this.start, 1), evt.triggeredByUser); |
394 this.speak(this.value.substr(evt.start)); | 394 this.speak(this.value.substr(evt.start)); |
395 } else if (this.start == this.end) { | 395 } else if (this.start == this.end) { |
396 // It was previously a cursor. | 396 // It was previously a cursor. |
397 this.speak(this.value.substr(evt.start, evt.end - evt.start), | 397 this.speak(this.value.substr(evt.start, evt.end - evt.start), |
398 evt.triggeredByUser); | 398 evt.triggeredByUser); |
399 this.speak(cvox.ChromeVox.msgs.getMsg('selected')); | 399 this.speak(Msgs.getMsg('selected')); |
400 } else if (this.start == evt.start && this.end < evt.end) { | 400 } else if (this.start == evt.start && this.end < evt.end) { |
401 this.speak(this.value.substr(this.end, evt.end - this.end), | 401 this.speak(this.value.substr(this.end, evt.end - this.end), |
402 evt.triggeredByUser); | 402 evt.triggeredByUser); |
403 this.speak(cvox.ChromeVox.msgs.getMsg('added_to_selection')); | 403 this.speak(Msgs.getMsg('added_to_selection')); |
404 } else if (this.start == evt.start && this.end > evt.end) { | 404 } else if (this.start == evt.start && this.end > evt.end) { |
405 this.speak(this.value.substr(evt.end, this.end - evt.end), | 405 this.speak(this.value.substr(evt.end, this.end - evt.end), |
406 evt.triggeredByUser); | 406 evt.triggeredByUser); |
407 this.speak(cvox.ChromeVox.msgs.getMsg('removed_from_selection')); | 407 this.speak(Msgs.getMsg('removed_from_selection')); |
408 } else if (this.end == evt.end && this.start > evt.start) { | 408 } else if (this.end == evt.end && this.start > evt.start) { |
409 this.speak(this.value.substr(evt.start, this.start - evt.start), | 409 this.speak(this.value.substr(evt.start, this.start - evt.start), |
410 evt.triggeredByUser); | 410 evt.triggeredByUser); |
411 this.speak(cvox.ChromeVox.msgs.getMsg('added_to_selection')); | 411 this.speak(Msgs.getMsg('added_to_selection')); |
412 } else if (this.end == evt.end && this.start < evt.start) { | 412 } else if (this.end == evt.end && this.start < evt.start) { |
413 this.speak(this.value.substr(this.start, evt.start - this.start), | 413 this.speak(this.value.substr(this.start, evt.start - this.start), |
414 evt.triggeredByUser); | 414 evt.triggeredByUser); |
415 this.speak(cvox.ChromeVox.msgs.getMsg('removed_from_selection')); | 415 this.speak(Msgs.getMsg('removed_from_selection')); |
416 } else { | 416 } else { |
417 // The selection changed but it wasn't an obvious extension of | 417 // The selection changed but it wasn't an obvious extension of |
418 // a previous selection. Just read the new selection. | 418 // a previous selection. Just read the new selection. |
419 this.speak(this.value.substr(evt.start, evt.end - evt.start), | 419 this.speak(this.value.substr(evt.start, evt.end - evt.start), |
420 evt.triggeredByUser); | 420 evt.triggeredByUser); |
421 this.speak(cvox.ChromeVox.msgs.getMsg('selected')); | 421 this.speak(Msgs.getMsg('selected')); |
422 } | 422 } |
423 } | 423 } |
424 }; | 424 }; |
425 | 425 |
426 | 426 |
427 /** | 427 /** |
428 * Describe a change where the text changes. | 428 * Describe a change where the text changes. |
429 * @param {cvox.TextChangeEvent} evt The text change event. | 429 * @param {cvox.TextChangeEvent} evt The text change event. |
430 */ | 430 */ |
431 cvox.ChromeVoxEditableTextBase.prototype.describeTextChanged = function(evt) { | 431 cvox.ChromeVoxEditableTextBase.prototype.describeTextChanged = function(evt) { |
432 var personality = {}; | 432 var personality = {}; |
433 if (evt.value.length < this.value.length) { | 433 if (evt.value.length < this.value.length) { |
434 personality = cvox.AbstractTts.PERSONALITY_DELETED; | 434 personality = cvox.AbstractTts.PERSONALITY_DELETED; |
435 } | 435 } |
436 if (this.isPassword) { | 436 if (this.isPassword) { |
437 this.speak((new goog.i18n.MessageFormat(cvox.ChromeVox.msgs.getMsg('dot')) | 437 this.speak((new goog.i18n.MessageFormat(Msgs.getMsg('dot')) |
438 .format({'COUNT': 1})), evt.triggeredByUser, personality); | 438 .format({'COUNT': 1})), evt.triggeredByUser, personality); |
439 return; | 439 return; |
440 } | 440 } |
441 | 441 |
442 var value = this.value; | 442 var value = this.value; |
443 var len = value.length; | 443 var len = value.length; |
444 var newLen = evt.value.length; | 444 var newLen = evt.value.length; |
445 var autocompleteSuffix = ''; | 445 var autocompleteSuffix = ''; |
446 // Make a copy of evtValue and evtEnd to avoid changing anything in | 446 // Make a copy of evtValue and evtEnd to avoid changing anything in |
447 // the event itself. | 447 // the event itself. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 } else if (value.indexOf(evtValue) == 1) { | 524 } else if (value.indexOf(evtValue) == 1) { |
525 this.speak(value[0], evt.triggeredByUser, personality); | 525 this.speak(value[0], evt.triggeredByUser, personality); |
526 return; | 526 return; |
527 } | 527 } |
528 } | 528 } |
529 } | 529 } |
530 | 530 |
531 if (this.multiline) { | 531 if (this.multiline) { |
532 // Fall back to announce deleted but omit the text that was deleted. | 532 // Fall back to announce deleted but omit the text that was deleted. |
533 if (evt.value.length < this.value.length) { | 533 if (evt.value.length < this.value.length) { |
534 this.speak(cvox.ChromeVox.msgs.getMsg('text_deleted'), | 534 this.speak(Msgs.getMsg('text_deleted'), |
535 evt.triggeredByUser, personality); | 535 evt.triggeredByUser, personality); |
536 } | 536 } |
537 // The below is a somewhat loose way to deal with non-standard | 537 // The below is a somewhat loose way to deal with non-standard |
538 // insertions/deletions. Intentionally skip for multiline since deletion | 538 // insertions/deletions. Intentionally skip for multiline since deletion |
539 // announcements are covered above and insertions are non-standard (possibly | 539 // announcements are covered above and insertions are non-standard (possibly |
540 // due to auto complete). Since content editable's often refresh content by | 540 // due to auto complete). Since content editable's often refresh content by |
541 // removing and inserting entire chunks of text, this type of logic often | 541 // removing and inserting entire chunks of text, this type of logic often |
542 // results in unintended consequences such as reading all text when only one | 542 // results in unintended consequences such as reading all text when only one |
543 // character has been entered. | 543 // character has been entered. |
544 return; | 544 return; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 | 703 |
704 /** | 704 /** |
705 * Moves the cursor backward by one paragraph. | 705 * Moves the cursor backward by one paragraph. |
706 * @return {boolean} True if the action was handled. | 706 * @return {boolean} True if the action was handled. |
707 */ | 707 */ |
708 cvox.ChromeVoxEditableTextBase.prototype.moveCursorToPreviousParagraph = | 708 cvox.ChromeVoxEditableTextBase.prototype.moveCursorToPreviousParagraph = |
709 function() { return false; }; | 709 function() { return false; }; |
710 | 710 |
711 | 711 |
712 /******************************************/ | 712 /******************************************/ |
OLD | NEW |