Bug 1272491 - fire xpcom show/hide events with e10s. r=tbsaunde
authorYura Zenevich <yzenevich@mozilla.com>
Fri, 13 May 2016 10:27:52 -0400
changeset 371003 ddaa43e26575a1c5c0248d4826c9e30e65162ef1
parent 371002 388863b89c72f99246748a5ee96131cd8d69b420
child 371004 eb567ace229f27e07ad7763ca81be68b08c04fa7
push id19197
push userbmo:tchiovoloni@mozilla.com
push dateWed, 25 May 2016 18:25:46 +0000
reviewerstbsaunde
bugs1272491
milestone49.0a1
Bug 1272491 - fire xpcom show/hide events with e10s. r=tbsaunde MozReview-Commit-ID: 9nwyHJMdlwO
accessible/ipc/DocAccessibleParent.cpp
accessible/tests/browser/browser.ini
accessible/tests/browser/events.js
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -59,17 +59,31 @@ DocAccessibleParent::RecvShowEvent(const
   for (uint32_t i = 0; i < consumed; i++) {
     uint64_t id = aData.NewTree()[i].ID();
     MOZ_ASSERT(mAccessibles.GetEntry(id));
   }
 #endif
 
   MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());
 
-  ProxyShowHideEvent(parent->ChildAt(newChildIdx), parent, true, aFromUser);
+  ProxyAccessible* target = parent->ChildAt(newChildIdx);
+  ProxyShowHideEvent(target, parent, true, aFromUser);
+
+  if (!nsCoreUtils::AccEventObserversExist()) {
+    return true;
+  }
+
+  uint32_t type = nsIAccessibleEvent::EVENT_SHOW;
+  xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(target);
+  xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
+  nsIDOMNode* node = nullptr;
+  RefPtr<xpcAccEvent> event = new xpcAccEvent(type, xpcAcc, doc, node,
+                                              aFromUser);
+  nsCoreUtils::DispatchAccEvent(Move(event));
+
   return true;
 }
 
 uint32_t
 DocAccessibleParent::AddSubtree(ProxyAccessible* aParent,
                                 const nsTArray<a11y::AccessibleData>& aNewTree,
                                 uint32_t aIdx, uint32_t aIdxInParent)
 {
@@ -136,21 +150,41 @@ DocAccessibleParent::RecvHideEvent(const
   ProxyAccessible* root = rootEntry->mProxy;
   if (!root) {
     NS_ERROR("invalid root being removed!");
     return true;
   }
 
   ProxyAccessible* parent = root->Parent();
   ProxyShowHideEvent(root, parent, false, aFromUser);
+
+  RefPtr<xpcAccHideEvent> event = nullptr;
+  if (nsCoreUtils::AccEventObserversExist()) {
+    uint32_t type = nsIAccessibleEvent::EVENT_HIDE;
+    xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(root);
+    xpcAccessibleGeneric* xpcParent = GetXPCAccessible(parent);
+    ProxyAccessible* next = root->NextSibling();
+    xpcAccessibleGeneric* xpcNext = next ? GetXPCAccessible(next) : nullptr;
+    ProxyAccessible* prev = root->PrevSibling();
+    xpcAccessibleGeneric* xpcPrev = prev ? GetXPCAccessible(prev) : nullptr;
+    xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
+    nsIDOMNode* node = nullptr;
+    event = new xpcAccHideEvent(type, xpcAcc, doc, node, aFromUser, xpcParent,
+                                xpcNext, xpcPrev);
+  }
+
   parent->RemoveChild(root);
   root->Shutdown();
 
   MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());
 
+  if (event) {
+    nsCoreUtils::DispatchAccEvent(Move(event));
+  }
+
   return true;
 }
 
 bool
 DocAccessibleParent::RecvEvent(const uint64_t& aID, const uint32_t& aEventType)
 {
   ProxyAccessible* proxy = GetAccessible(aID);
   if (!proxy) {
--- a/accessible/tests/browser/browser.ini
+++ b/accessible/tests/browser/browser.ini
@@ -15,29 +15,25 @@ support-files =
 
 # Caching tests
 [browser_caching_name.js]
 skip-if = e10s
 
 # Events tests
 [browser_events_caretmove.js]
 [browser_events_hide.js]
-skip-if = e10s
 [browser_events_show.js]
-skip-if = e10s
 [browser_events_statechange.js]
 [browser_events_textchange.js]
 
 # Tree update tests
 [browser_treeupdate_ariadialog.js]
-skip-if = e10s
 [browser_treeupdate_ariaowns.js]
 skip-if = e10s
 [browser_treeupdate_canvas.js]
-skip-if = e10s
 [browser_treeupdate_cssoverflow.js]
 [browser_treeupdate_doc.js]
 skip-if = e10s
 [browser_treeupdate_gencontent.js]
 [browser_treeupdate_hidden.js]
 [browser_treeupdate_imagemap.js]
 skip-if = e10s
 [browser_treeupdate_list.js]
--- a/accessible/tests/browser/events.js
+++ b/accessible/tests/browser/events.js
@@ -37,38 +37,54 @@ function eventToString(event) {
     info += `, start: ${event.start}, length: ${event.length}, ${tcType} text: ${event.modifiedText}`;
   }
 
   info += `. Target: ${prettyName(event.accessible)}`;
   return info;
 }
 
 /**
- * A helper function that waits for an accessible event of certain type that
- * belongs to a certain DOMNode (defined by its id).
- * @param  {String}  id         expected content element id for the event
- * @param  {Number}  eventType  expected accessible event type
- * @return {Promise}            promise that resolves to an event
+ * A helper function that returns a promise that resolves when an accessible
+ * event of the given type with the given target (defined by its id or
+ * accessible) is observed.
+ * @param  {String|nsIAccessible}  expectedIdOrAcc  expected content element id
+ *                                                  for the event
+ * @param  {Number}                eventType        expected accessible event
+ *                                                  type
+ * @return {Promise}                                promise that resolves to an
+ *                                                  event
  */
-function waitForEvent(eventType, id) {
+function waitForEvent(eventType, expectedIdOrAcc) {
   return new Promise(resolve => {
     let eventObserver = {
       observe(subject, topic, data) {
         if (topic !== 'accessible-event') {
           return;
         }
 
         let event = subject.QueryInterface(nsIAccessibleEvent);
         Logger.log(eventToString(event));
 
-        let domID = getAccessibleDOMNodeID(event.accessible);
-        // If event's accessible does not match expected event type or DOMNode
-        // id, skip thie event.
-        if (domID === id && event.eventType === eventType) {
-          Logger.log(`Correct event DOMNode id: ${id}`);
+        // If event type does not match expected type, skip the event.
+        if (event.eventType !== eventType) {
+          return;
+        }
+
+        let acc = event.accessible;
+        let id = getAccessibleDOMNodeID(acc);
+        let isID = typeof expectedIdOrAcc === 'string';
+        let actualIdOrAcc = isID ? id : acc;
+        // If event's accessible does not match expected DOMNode id or
+        // accessible, skip the event.
+        if (actualIdOrAcc === expectedIdOrAcc) {
+          if (isID) {
+            Logger.log(`Correct event DOMNode id: ${id}`);
+          } else {
+            Logger.log(`Correct event accessible: ${prettyName(acc)}`);
+          }
           Logger.log(`Correct event type: ${eventTypeToString(eventType)}`);
           ok(event.accessibleDocument instanceof nsIAccessibleDocument,
             'Accessible document present.');
 
           Services.obs.removeObserver(this, 'accessible-event');
           resolve(event);
         }
       }