Bug 1129955 - added support for accessible name changes in AccessFu. r=eeejay
authorYura Zenevich <yzenevich@mozilla.com>
Thu, 05 Feb 2015 14:06:53 -0500
changeset 227744 d9f7bafe9b47d69216c2b9abddf8026ef177c905
parent 227743 39f991c2bd718d10c7fb3ed4611b85843a59b918
child 227745 823612c80ff83503359c1f62775f84722801631f
push id28238
push userkwierso@gmail.com
push dateFri, 06 Feb 2015 00:55:16 +0000
treeherdermozilla-central@7c5f187b65bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerseeejay
bugs1129955
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1129955 - added support for accessible name changes in AccessFu. r=eeejay --- accessible/jsat/EventManager.jsm | 8 ++++++++ accessible/jsat/Presentation.jsm | 21 ++++++++++++++++++++ .../mochitest/jsat/doc_content_integration.html | 5 +++++ accessible/tests/mochitest/jsat/jsatcommon.js | 9 +++++++++ .../mochitest/jsat/test_content_integration.html | 23 +++++++++++++++++++--- 5 files changed, 63 insertions(+), 3 deletions(-)
accessible/jsat/EventManager.jsm
accessible/jsat/Presentation.jsm
accessible/tests/mochitest/jsat/doc_content_integration.html
accessible/tests/mochitest/jsat/jsatcommon.js
accessible/tests/mochitest/jsat/test_content_integration.html
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -181,16 +181,24 @@ this.EventManager.prototype = {
         } else if (state.contains(States.SELECTED)) {
           this.present(
             Presentation.
               actionInvoked(aEvent.accessible,
                             event.isEnabled ? 'select' : 'unselect'));
         }
         break;
       }
+      case Events.NAME_CHANGE:
+      {
+        let acc = aEvent.accessible;
+        if (acc === this.contentControl.vc.position) {
+          this.present(Presentation.nameChanged(acc));
+        }
+        break;
+      }
       case Events.SCROLLING_START:
       {
         this.contentControl.autoMove(aEvent.accessible);
         break;
       }
       case Events.TEXT_CARET_MOVED:
       {
         let acc = aEvent.accessible.QueryInterface(Ci.nsIAccessibleText);
--- a/accessible/jsat/Presentation.jsm
+++ b/accessible/jsat/Presentation.jsm
@@ -70,16 +70,22 @@ Presenter.prototype = {
 
   /**
    * Selection has changed. TODO.
    * @param {nsIAccessible} aObject the object that has been selected.
    */
   selectionChanged: function selectionChanged(aObject) {}, // jshint ignore:line
 
   /**
+   * Name has changed.
+   * @param {nsIAccessible} aAccessible the object whose value has changed.
+   */
+  nameChanged: function nameChanged(aAccessible) {}, // jshint ignore: line
+
+  /**
    * Value has changed.
    * @param {nsIAccessible} aAccessible the object whose value has changed.
    */
   valueChanged: function valueChanged(aAccessible) {}, // jshint ignore:line
 
   /**
    * The tab, or the tab's document state has changed.
    * @param {nsIAccessible} aDocObj the tab document accessible that has had its
@@ -509,16 +515,27 @@ B2GPresenter.prototype.pivotChanged =
           reason: this.pivotChangedReasons[aReason],
           isUserInput: aIsUserInput,
           hints: aContext.interactionHints
         }
       }
     };
   };
 
+B2GPresenter.prototype.nameChanged =
+  function B2GPresenter_nameChanged(aAccessible) {
+    return {
+      type: this.type,
+      details: {
+        eventType: 'name-change',
+        data: aAccessible.name
+      }
+    };
+  };
+
 B2GPresenter.prototype.valueChanged =
   function B2GPresenter_valueChanged(aAccessible) {
 
     // the editable value changes are handled in the text changed presenter
     if (Utils.getState(aAccessible).contains(States.EDITABLE)) {
       return null;
     }
 
@@ -684,16 +701,20 @@ this.Presentation = { // jshint ignore:l
 
   textSelectionChanged: function textSelectionChanged(aText, aStart, aEnd,
                                                       aOldStart, aOldEnd,
                                                       aIsFromUserInput) {
     return [p.textSelectionChanged(aText, aStart, aEnd, aOldStart, aOldEnd, // jshint ignore:line
       aIsFromUserInput) for each (p in this.presenters)]; // jshint ignore:line
   },
 
+  nameChanged: function nameChanged(aAccessible) {
+    return [ p.nameChanged(aAccessible) for (p of this.presenters) ]; // jshint ignore:line
+  },
+
   valueChanged: function valueChanged(aAccessible) {
     return [ p.valueChanged(aAccessible) for (p of this.presenters) ]; // jshint ignore:line
   },
 
   tabStateChanged: function Presentation_tabStateChanged(aDocObj, aPageState) {
     return [p.tabStateChanged(aDocObj, aPageState) // jshint ignore:line
       for each (p in this.presenters)]; // jshint ignore:line
   },
--- a/accessible/tests/mochitest/jsat/doc_content_integration.html
+++ b/accessible/tests/mochitest/jsat/doc_content_integration.html
@@ -35,16 +35,20 @@
     function ariaShowIframe() {
       document.getElementById('iframe').setAttribute('aria-hidden', false);
     }
 
     function ariaHideIframe() {
       document.getElementById('iframe').setAttribute('aria-hidden', true);
     }
 
+    function renameFruit() {
+      document.getElementById('fruit').setAttribute('aria-label', 'banana');
+    }
+
   </script>
   <style>
     #windows {
       position: relative;
       width: 320px;
       height: 480px;
     }
 
@@ -79,10 +83,11 @@
       <h1>This is an alert!</h1>
       <p>Do you agree?</p>
       <button onclick="setTimeout(hideAlert, 500)">Yes</button>
       <button onclick="hideAlert()">No</button>
     </div>
     <div id="appframe"></div>
   </div>
   <button id="home">Home</button>
+  <button id="fruit" aria-label="apple"></button>
 </body>
 </html>
--- a/accessible/tests/mochitest/jsat/jsatcommon.js
+++ b/accessible/tests/mochitest/jsat/jsatcommon.js
@@ -612,16 +612,25 @@ function ExpectedCheckAction(aChecked, a
   }, [{
     eventType: AndroidEvent.VIEW_CLICKED,
     checked: aChecked
   }], aOptions);
 }
 
 ExpectedCheckAction.prototype = Object.create(ExpectedPresent.prototype);
 
+function ExpectedNameChange(aName, aOptions) {
+  ExpectedPresent.call(this, {
+    eventType: 'name-change',
+    data: aName
+  }, null, aOptions);
+}
+
+ExpectedNameChange.prototype = Object.create(ExpectedPresent.prototype);
+
 function ExpectedValueChange(aValue, aOptions) {
   ExpectedPresent.call(this, {
     eventType: 'value-change',
     data: [aValue]
   }, null, aOptions);
 }
 
 ExpectedValueChange.prototype = Object.create(ExpectedPresent.prototype);
--- a/accessible/tests/mochitest/jsat/test_content_integration.html
+++ b/accessible/tests/mochitest/jsat/test_content_integration.html
@@ -51,19 +51,23 @@
            new ExpectedCheckAction(true, { android_todo: true })],
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(['much range', {'string': 'label'}])],
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(['much range', '5', {'string': 'slider'}])],
           [ContentMessages.moveOrAdjustUp(), new ExpectedValueChange('6')],
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
+          [ContentMessages.simpleMoveNext,
+           new ExpectedCursorChange(['apple', {'string': 'pushbutton'}])],
 
           // Simple traversal backward
           [ContentMessages.simpleMovePrevious,
+           new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
+          [ContentMessages.simpleMovePrevious,
            new ExpectedCursorChange(['much range', '6', {'string': 'slider'}, 'such app'])],
           [ContentMessages.moveOrAdjustDown(), new ExpectedValueChange('5')],
           [ContentMessages.simpleMovePrevious,
            new ExpectedCursorChange(['much range', {'string': 'label'}])],
           [ContentMessages.simpleMovePrevious,
            new ExpectedCursorChange(['many option', {'string': 'stateChecked'},
             {'string': 'checkbutton'}, {'string': 'listStart'},
             {'string': 'list'}, {'string': 'listItemsCount', 'count': 1}])],
@@ -83,17 +87,17 @@
           // Moving to the absolute last item from an embedded document
           // fails. Bug 972035.
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(
             ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'])],
           // Move from an inner frame to the last element in the parent doc
           [ContentMessages.simpleMoveLast,
             new ExpectedCursorChange(
-              ['Home', {'string': 'pushbutton'}], { b2g_todo: true })],
+              ['apple', {'string': 'pushbutton'}], { b2g_todo: true })],
 
           [ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
 
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
           [ContentMessages.moveOrAdjustDown('FormElement'),
            new ExpectedCursorChange(['Back', {"string": "pushbutton"}])],
           [ContentMessages.moveOrAdjustDown('FormElement'),
@@ -131,16 +135,27 @@
              {'string': 'checkbutton'}, {'string': 'listStart'},
              {'string': 'list'}, {'string': 'listItemsCount', 'count': 1}])],
           [ContentMessages.simpleMoveFirst,
             new ExpectedCursorChange(['Phone status bar'], { b2g_todo: true })],
 
           // Reset cursors
           [ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
 
+          // Current virtual cursor's position's name changes
+          [ContentMessages.simpleMoveNext,
+           new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
+          [ContentMessages.focusSelector('button#fruit', false),
+           new ExpectedCursorChange(['apple', {'string': 'pushbutton'}])],
+          [doc.defaultView.renameFruit, new ExpectedNameChange('banana')],
+
+          // Blur button and reset cursor
+          [ContentMessages.focusSelector('button#fruit', true), null],
+          [ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
+
           // Move cursor with focus in outside document
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
           [ContentMessages.focusSelector('button#home', false),
            new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
 
           // Blur button and reset cursor
           [ContentMessages.focusSelector('button#home', true), null],
@@ -202,24 +217,24 @@
            new ExpectedCursorChange(
              ["wow", {"string": "headingLevel","args": [1]}, "such app"])],
           [doc.defaultView.ariaShowBack],
           [ContentMessages.focusSelector('button#back', true), null],
           [ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
 
           // Open dialog in outer doc, while cursor is also in outer doc
           [ContentMessages.simpleMoveLast,
-           new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
+           new ExpectedCursorChange(['banana', {'string': 'pushbutton'}])],
           [doc.defaultView.showAlert,
             new ExpectedCursorChange(['This is an alert!',
               {'string': 'headingLevel', 'args': [1]},
               {'string': 'dialog'}])],
 
           [doc.defaultView.hideAlert,
-           new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
+           new ExpectedCursorChange(['banana', {'string': 'pushbutton'}])],
 
           [ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
 
           // Open dialog in outer doc, while cursor is in inner frame
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(['Phone status bar', 'Traversal Rule test document'])],
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
@@ -248,16 +263,18 @@
            new ExpectedCursorChange(['This is an alert!',
             {'string': 'headingLevel', 'args': [1]}, {'string': 'dialog'}])],
 
           [function hideAlertAndFocusHomeButton() {
             doc.defaultView.hideAlert();
             doc.querySelector('button#home').focus();
           }, new ExpectedCursorChange(['Home', {'string': 'pushbutton'},
             'Traversal Rule test document'])],
+          [ContentMessages.simpleMoveNext,
+            new ExpectedCursorChange(['banana', {'string': 'pushbutton'}])]
           [ContentMessages.simpleMoveNext, new ExpectedNoMove()]
         ]);
 
         addA11yLoadEvent(function() {
           contentTest.start(function () {
             closeBrowserWindow();
             SimpleTest.finish();
           });