| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 ChromeVox commands. | 6 * @fileoverview ChromeVox commands. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 goog.provide('CommandHandler'); | 9 goog.provide('CommandHandler'); |
| 10 | 10 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 | 35 |
| 36 if (!focusedNode) | 36 if (!focusedNode) |
| 37 ChromeVoxState.instance.setCurrentRange(null); | 37 ChromeVoxState.instance.setCurrentRange(null); |
| 38 }); | 38 }); |
| 39 | 39 |
| 40 // These commands don't require a current range and work in all modes. | 40 // These commands don't require a current range and work in all modes. |
| 41 switch (command) { | 41 switch (command) { |
| 42 case 'speakTimeAndDate': | 42 case 'speakTimeAndDate': |
| 43 chrome.automation.getDesktop(function(d) { | 43 chrome.automation.getDesktop(function(d) { |
| 44 // First, try speaking the on-screen time. | 44 // First, try speaking the on-screen time. |
| 45 var allTime = d.findAll({role: RoleType.TIME}); | 45 var allTime = d.findAll({role: RoleType.time}); |
| 46 allTime.filter(function(t) { return t.root.role == RoleType.DESKTOP; }); | 46 allTime.filter(function(t) { return t.root.role == RoleType.desktop; }); |
| 47 | 47 |
| 48 var timeString = ''; | 48 var timeString = ''; |
| 49 allTime.forEach(function(t) { | 49 allTime.forEach(function(t) { |
| 50 if (t.name) timeString = t.name; | 50 if (t.name) timeString = t.name; |
| 51 }); | 51 }); |
| 52 if (timeString) { | 52 if (timeString) { |
| 53 cvox.ChromeVox.tts.speak(timeString, cvox.QueueMode.FLUSH); | 53 cvox.ChromeVox.tts.speak(timeString, cvox.QueueMode.FLUSH); |
| 54 } else { | 54 } else { |
| 55 // Fallback to the old way of speaking time. | 55 // Fallback to the old way of speaking time. |
| 56 var output = new Output(); | 56 var output = new Output(); |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 break; | 438 break; |
| 439 case 'jumpToBottom': | 439 case 'jumpToBottom': |
| 440 var node = AutomationUtil.findNodePost( | 440 var node = AutomationUtil.findNodePost( |
| 441 current.start.node.root, Dir.BACKWARD, AutomationPredicate.leaf); | 441 current.start.node.root, Dir.BACKWARD, AutomationPredicate.leaf); |
| 442 if (node) | 442 if (node) |
| 443 current = cursors.Range.fromNode(node); | 443 current = cursors.Range.fromNode(node); |
| 444 break; | 444 break; |
| 445 case 'forceClickOnCurrentItem': | 445 case 'forceClickOnCurrentItem': |
| 446 if (ChromeVoxState.instance.currentRange_) { | 446 if (ChromeVoxState.instance.currentRange_) { |
| 447 var actionNode = ChromeVoxState.instance.currentRange_.start.node; | 447 var actionNode = ChromeVoxState.instance.currentRange_.start.node; |
| 448 if (actionNode.role == RoleType.INLINE_TEXT_BOX) | 448 if (actionNode.role == RoleType.inlineTextBox) |
| 449 actionNode = actionNode.parent; | 449 actionNode = actionNode.parent; |
| 450 actionNode.doDefault(); | 450 actionNode.doDefault(); |
| 451 } | 451 } |
| 452 // Skip all other processing; if focus changes, we should get an event | 452 // Skip all other processing; if focus changes, we should get an event |
| 453 // for that. | 453 // for that. |
| 454 return false; | 454 return false; |
| 455 case 'readFromHere': | 455 case 'readFromHere': |
| 456 ChromeVoxState.isReadingContinuously = true; | 456 ChromeVoxState.isReadingContinuously = true; |
| 457 var continueReading = function() { | 457 var continueReading = function() { |
| 458 if (!ChromeVoxState.isReadingContinuously || | 458 if (!ChromeVoxState.isReadingContinuously || |
| 459 !ChromeVoxState.instance.currentRange_) | 459 !ChromeVoxState.instance.currentRange_) |
| 460 return; | 460 return; |
| 461 | 461 |
| 462 var prevRange = ChromeVoxState.instance.currentRange_; | 462 var prevRange = ChromeVoxState.instance.currentRange_; |
| 463 var newRange = | 463 var newRange = |
| 464 ChromeVoxState.instance.currentRange_.move( | 464 ChromeVoxState.instance.currentRange_.move( |
| 465 cursors.Unit.NODE, Dir.FORWARD); | 465 cursors.Unit.NODE, Dir.FORWARD); |
| 466 | 466 |
| 467 // Stop if we've wrapped back to the document. | 467 // Stop if we've wrapped back to the document. |
| 468 var maybeDoc = newRange.start.node; | 468 var maybeDoc = newRange.start.node; |
| 469 if (maybeDoc.role == RoleType.ROOT_WEB_AREA && | 469 if (maybeDoc.role == RoleType.rootWebArea && |
| 470 maybeDoc.parent.root.role == RoleType.DESKTOP) { | 470 maybeDoc.parent.root.role == RoleType.desktop) { |
| 471 ChromeVoxState.isReadingContinuously = false; | 471 ChromeVoxState.isReadingContinuously = false; |
| 472 return; | 472 return; |
| 473 } | 473 } |
| 474 | 474 |
| 475 ChromeVoxState.instance.setCurrentRange(newRange); | 475 ChromeVoxState.instance.setCurrentRange(newRange); |
| 476 | 476 |
| 477 new Output() | 477 new Output() |
| 478 .withRichSpeechAndBraille(ChromeVoxState.instance.currentRange_, | 478 .withRichSpeechAndBraille(ChromeVoxState.instance.currentRange_, |
| 479 prevRange, | 479 prevRange, |
| 480 Output.EventType.NAVIGATE) | 480 Output.EventType.NAVIGATE) |
| 481 .onSpeechEnd(continueReading) | 481 .onSpeechEnd(continueReading) |
| 482 .go(); | 482 .go(); |
| 483 }.bind(this); | 483 }.bind(this); |
| 484 | 484 |
| 485 new Output() | 485 new Output() |
| 486 .withRichSpeechAndBraille(ChromeVoxState.instance.currentRange_, | 486 .withRichSpeechAndBraille(ChromeVoxState.instance.currentRange_, |
| 487 null, | 487 null, |
| 488 Output.EventType.NAVIGATE) | 488 Output.EventType.NAVIGATE) |
| 489 .onSpeechEnd(continueReading) | 489 .onSpeechEnd(continueReading) |
| 490 .go(); | 490 .go(); |
| 491 | 491 |
| 492 return false; | 492 return false; |
| 493 case 'contextMenu': | 493 case 'contextMenu': |
| 494 if (ChromeVoxState.instance.currentRange_) { | 494 if (ChromeVoxState.instance.currentRange_) { |
| 495 var actionNode = ChromeVoxState.instance.currentRange_.start.node; | 495 var actionNode = ChromeVoxState.instance.currentRange_.start.node; |
| 496 if (actionNode.role == RoleType.INLINE_TEXT_BOX) | 496 if (actionNode.role == RoleType.inlineTextBox) |
| 497 actionNode = actionNode.parent; | 497 actionNode = actionNode.parent; |
| 498 actionNode.showContextMenu(); | 498 actionNode.showContextMenu(); |
| 499 return false; | 499 return false; |
| 500 } | 500 } |
| 501 break; | 501 break; |
| 502 case 'toggleKeyboardHelp': | 502 case 'toggleKeyboardHelp': |
| 503 (new PanelCommand(PanelCommandType.OPEN_MENUS)).send(); | 503 (new PanelCommand(PanelCommandType.OPEN_MENUS)).send(); |
| 504 return false; | 504 return false; |
| 505 case 'showHeadingsList': | 505 case 'showHeadingsList': |
| 506 (new PanelCommand(PanelCommandType.OPEN_MENUS, 'role_heading')).send(); | 506 (new PanelCommand(PanelCommandType.OPEN_MENUS, 'role_heading')).send(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 517 case 'showTablesList': | 517 case 'showTablesList': |
| 518 (new PanelCommand(PanelCommandType.OPEN_MENUS, 'table_strategy')).send(); | 518 (new PanelCommand(PanelCommandType.OPEN_MENUS, 'table_strategy')).send(); |
| 519 return false; | 519 return false; |
| 520 case 'toggleSearchWidget': | 520 case 'toggleSearchWidget': |
| 521 (new PanelCommand(PanelCommandType.SEARCH)).send(); | 521 (new PanelCommand(PanelCommandType.SEARCH)).send(); |
| 522 return false; | 522 return false; |
| 523 case 'readCurrentTitle': | 523 case 'readCurrentTitle': |
| 524 var target = ChromeVoxState.instance.currentRange_.start.node; | 524 var target = ChromeVoxState.instance.currentRange_.start.node; |
| 525 var output = new Output(); | 525 var output = new Output(); |
| 526 | 526 |
| 527 if (target.root.role == RoleType.ROOT_WEB_AREA) { | 527 if (target.root.role == RoleType.rootWebArea) { |
| 528 // Web. | 528 // Web. |
| 529 target = target.root; | 529 target = target.root; |
| 530 output.withString(target.name || target.docUrl); | 530 output.withString(target.name || target.docUrl); |
| 531 } else { | 531 } else { |
| 532 // Views. | 532 // Views. |
| 533 while (target.role != RoleType.WINDOW) target = target.parent; | 533 while (target.role != RoleType.window) target = target.parent; |
| 534 if (target) | 534 if (target) |
| 535 output.withString(target.name || ''); | 535 output.withString(target.name || ''); |
| 536 } | 536 } |
| 537 output.go(); | 537 output.go(); |
| 538 return false; | 538 return false; |
| 539 case 'readCurrentURL': | 539 case 'readCurrentURL': |
| 540 var output = new Output(); | 540 var output = new Output(); |
| 541 var target = ChromeVoxState.instance.currentRange_.start.node.root; | 541 var target = ChromeVoxState.instance.currentRange_.start.node.root; |
| 542 output.withString(target.docUrl || '').go(); | 542 output.withString(target.docUrl || '').go(); |
| 543 return false; | 543 return false; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 dir = Dir.FORWARD; | 608 dir = Dir.FORWARD; |
| 609 var tableOpts = {col: true, dir: dir}; | 609 var tableOpts = {col: true, dir: dir}; |
| 610 pred = AutomationPredicate.makeTableCellPredicate( | 610 pred = AutomationPredicate.makeTableCellPredicate( |
| 611 current.start.node, tableOpts); | 611 current.start.node, tableOpts); |
| 612 predErrorMsg = 'no_cell_right'; | 612 predErrorMsg = 'no_cell_right'; |
| 613 rootPred = AutomationPredicate.row; | 613 rootPred = AutomationPredicate.row; |
| 614 break; | 614 break; |
| 615 case 'goToRowFirstCell': | 615 case 'goToRowFirstCell': |
| 616 case 'goToRowLastCell': | 616 case 'goToRowLastCell': |
| 617 var node = current.start.node; | 617 var node = current.start.node; |
| 618 while (node && node.role != RoleType.ROW) | 618 while (node && node.role != RoleType.row) |
| 619 node = node.parent; | 619 node = node.parent; |
| 620 if (!node) | 620 if (!node) |
| 621 break; | 621 break; |
| 622 var end = AutomationUtil.findNodePost(node, | 622 var end = AutomationUtil.findNodePost(node, |
| 623 command == 'goToRowLastCell' ? Dir.BACKWARD : Dir.FORWARD, | 623 command == 'goToRowLastCell' ? Dir.BACKWARD : Dir.FORWARD, |
| 624 AutomationPredicate.leaf); | 624 AutomationPredicate.leaf); |
| 625 if (end) | 625 if (end) |
| 626 current = cursors.Range.fromNode(end); | 626 current = cursors.Range.fromNode(end); |
| 627 break; | 627 break; |
| 628 case 'goToColFirstCell': | 628 case 'goToColFirstCell': |
| 629 dir = Dir.FORWARD; | 629 dir = Dir.FORWARD; |
| 630 var node = current.start.node; | 630 var node = current.start.node; |
| 631 while (node && node.role != RoleType.TABLE) | 631 while (node && node.role != RoleType.table) |
| 632 node = node.parent; | 632 node = node.parent; |
| 633 if (!node || !node.firstChild) | 633 if (!node || !node.firstChild) |
| 634 return false; | 634 return false; |
| 635 var tableOpts = {col: true, dir: dir, end: true}; | 635 var tableOpts = {col: true, dir: dir, end: true}; |
| 636 pred = AutomationPredicate.makeTableCellPredicate( | 636 pred = AutomationPredicate.makeTableCellPredicate( |
| 637 current.start.node, tableOpts); | 637 current.start.node, tableOpts); |
| 638 current = cursors.Range.fromNode(node.firstChild); | 638 current = cursors.Range.fromNode(node.firstChild); |
| 639 // Should not be outputted. | 639 // Should not be outputted. |
| 640 predErrorMsg = 'no_cell_above'; | 640 predErrorMsg = 'no_cell_above'; |
| 641 rootPred = AutomationPredicate.table; | 641 rootPred = AutomationPredicate.table; |
| 642 break; | 642 break; |
| 643 case 'goToColLastCell': | 643 case 'goToColLastCell': |
| 644 dir = Dir.BACKWARD; | 644 dir = Dir.BACKWARD; |
| 645 var node = current.start.node; | 645 var node = current.start.node; |
| 646 while (node && node.role != RoleType.TABLE) | 646 while (node && node.role != RoleType.table) |
| 647 node = node.parent; | 647 node = node.parent; |
| 648 if (!node || !node.lastChild) | 648 if (!node || !node.lastChild) |
| 649 return false; | 649 return false; |
| 650 var tableOpts = {col: true, dir: dir, end: true}; | 650 var tableOpts = {col: true, dir: dir, end: true}; |
| 651 pred = AutomationPredicate.makeTableCellPredicate( | 651 pred = AutomationPredicate.makeTableCellPredicate( |
| 652 current.start.node, tableOpts); | 652 current.start.node, tableOpts); |
| 653 current = cursors.Range.fromNode(node.lastChild); | 653 current = cursors.Range.fromNode(node.lastChild); |
| 654 // Should not be outputted. | 654 // Should not be outputted. |
| 655 predErrorMsg = 'no_cell_below'; | 655 predErrorMsg = 'no_cell_below'; |
| 656 rootPred = AutomationPredicate.table; | 656 rootPred = AutomationPredicate.table; |
| 657 break; | 657 break; |
| 658 case 'goToFirstCell': | 658 case 'goToFirstCell': |
| 659 case 'goToLastCell': | 659 case 'goToLastCell': |
| 660 node = current.start.node; | 660 node = current.start.node; |
| 661 while (node && node.role != RoleType.TABLE) | 661 while (node && node.role != RoleType.table) |
| 662 node = node.parent; | 662 node = node.parent; |
| 663 if (!node) | 663 if (!node) |
| 664 break; | 664 break; |
| 665 var end = AutomationUtil.findNodePost(node, | 665 var end = AutomationUtil.findNodePost(node, |
| 666 command == 'goToLastCell' ? Dir.BACKWARD : Dir.FORWARD, | 666 command == 'goToLastCell' ? Dir.BACKWARD : Dir.FORWARD, |
| 667 AutomationPredicate.leaf); | 667 AutomationPredicate.leaf); |
| 668 if (end) | 668 if (end) |
| 669 current = cursors.Range.fromNode(end); | 669 current = cursors.Range.fromNode(end); |
| 670 break; | 670 break; |
| 671 default: | 671 default: |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 break; | 768 break; |
| 769 } | 769 } |
| 770 if (announcement) { | 770 if (announcement) { |
| 771 cvox.ChromeVox.tts.speak( | 771 cvox.ChromeVox.tts.speak( |
| 772 announcement, cvox.QueueMode.FLUSH, | 772 announcement, cvox.QueueMode.FLUSH, |
| 773 cvox.AbstractTts.PERSONALITY_ANNOTATION); | 773 cvox.AbstractTts.PERSONALITY_ANNOTATION); |
| 774 } | 774 } |
| 775 }; | 775 }; |
| 776 | 776 |
| 777 }); // goog.scope | 777 }); // goog.scope |
| OLD | NEW |