Merge mozilla-central to inbound. a=merge CLOSED TREE
authorshindli <shindli@mozilla.com>
Wed, 24 Oct 2018 12:50:15 +0300
changeset 491058 44190e77cd72ad04a263f8d8822bf3aeb267eadb
parent 491051 8be2131ed18337d6d5011d51aa9d9f39aefff495 (current diff)
parent 491057 3a314e76d8c148e223cf683b15ba2a357ebe4b42 (diff)
child 491060 3f33fb9163fcfe2fc6890808730d4a13a1769671
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersmerge
milestone65.0a1
Merge mozilla-central to inbound. a=merge CLOSED TREE
--- a/accessible/base/MarkupMap.h
+++ b/accessible/base/MarkupMap.h
@@ -323,19 +323,23 @@ MARKUPMAP(p,
 MARKUPMAP(progress,
           New_HTMLProgress,
           0)
 
 MARKUPMAP(q,
           New_HyperText,
           0)
 
-MARKUPMAP(section,
-          New_HyperText,
-          roles::SECTION)
+MARKUPMAP(
+  section,
+  [](Element* aElement, Accessible* aContext) -> Accessible* {
+     return new HTMLSectionAccessible(aElement, aContext->Document());
+  },
+  0
+)
 
 MARKUPMAP(summary,
           New_HTMLSummary,
           roles::SUMMARY)
 
 MARKUPMAP(
   table,
   [](Element* aElement, Accessible* aContext) -> Accessible* {
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -1489,17 +1489,17 @@ Accessible::ARIATransformRole(role aRole
   // case, it should not be especially bad here: If the author hasn't used the
   // region role, this calculation won't occur. And the region role's name
   // calculation rule excludes name from content. That said, this use case is
   // another example of why we should consider caching the accessible name. See:
   // https://bugzilla.mozilla.org/show_bug.cgi?id=1378235.
   if (aRole == roles::REGION) {
     nsAutoString name;
     Name(name);
-    return name.IsEmpty() ? NativeRole() : aRole;
+    return name.IsEmpty() ? NativeRole() : roles::LANDMARK;
   }
 
   // XXX: these unfortunate exceptions don't fit into the ARIA table. This is
   // where the accessible role depends on both the role and ARIA state.
   if (aRole == roles::PUSHBUTTON) {
     if (nsAccUtils::HasDefinedARIAToken(mContent, nsGkAtoms::aria_pressed)) {
       // For simplicity, any existing pressed attribute except "" or "undefined"
       // indicates a toggle.
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -1137,23 +1137,16 @@ HyperTextAccessible::LandmarkRole() cons
   if (mContent->IsHTMLElement(nsGkAtoms::aside)) {
     return nsGkAtoms::complementary;
   }
 
   if (mContent->IsHTMLElement(nsGkAtoms::main)) {
     return nsGkAtoms::main;
   }
 
-  // Only return xml-roles "region" if the section has an accessible name.
-  if (mContent->IsHTMLElement(nsGkAtoms::section)) {
-    nsAutoString name;
-    const_cast<HyperTextAccessible*>(this)->Name(name);
-    return name.IsEmpty() ? nullptr : nsGkAtoms::region;
-  }
-
   // Only return xml-roles "form" if the form has an accessible name.
   if (mContent->IsHTMLElement(nsGkAtoms::form)) {
     nsAutoString name;
     const_cast<HyperTextAccessible*>(this)->Name(name);
     return name.IsEmpty() ? nullptr : nsGkAtoms::form;
   }
 
   return nullptr;
--- a/accessible/html/HTMLElementAccessibles.cpp
+++ b/accessible/html/HTMLElementAccessibles.cpp
@@ -243,8 +243,34 @@ HTMLHeaderOrFooterAccessible::LandmarkRo
 
     if (mContent->IsHTMLElement(nsGkAtoms::footer)) {
       return nsGkAtoms::contentinfo;
     }
   }
 
   return nullptr;
 }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// HTMLSectionAccessible
+////////////////////////////////////////////////////////////////////////////////
+
+role
+HTMLSectionAccessible::NativeRole() const
+{
+  nsAutoString name;
+  const_cast<HTMLSectionAccessible*>(this)->Name(name);
+  return name.IsEmpty() ? roles::SECTION : roles::LANDMARK;
+}
+
+nsAtom*
+HTMLSectionAccessible::LandmarkRole() const
+{
+  if (!HasOwnContent()) {
+    return nullptr;
+  }
+
+  // Only return xml-roles "region" if the section has an accessible name.
+  nsAutoString name;
+  const_cast<HTMLSectionAccessible*>(this)->Name(name);
+  return name.IsEmpty() ? nullptr : nsGkAtoms::region;
+}
--- a/accessible/html/HTMLElementAccessibles.h
+++ b/accessible/html/HTMLElementAccessibles.h
@@ -132,12 +132,33 @@ public:
   // Accessible
   virtual nsAtom* LandmarkRole() const override;
   virtual a11y::role NativeRole() const override;
 
 protected:
   virtual ~HTMLHeaderOrFooterAccessible() {}
 };
 
+/**
+ * Used for HTML section element.
+ */
+class HTMLSectionAccessible : public HyperTextAccessibleWrap
+{
+public:
+
+  HTMLSectionAccessible(nsIContent* aContent, DocAccessible* aDoc) :
+    HyperTextAccessibleWrap(aContent, aDoc) {}
+
+  NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLSectionAccessible,
+                                       HyperTextAccessibleWrap)
+
+  // Accessible
+  virtual nsAtom* LandmarkRole() const override;
+  virtual a11y::role NativeRole() const override;
+
+protected:
+  virtual ~HTMLSectionAccessible() = default;
+};
+
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/tests/mochitest/elm/test_HTMLSpec.html
+++ b/accessible/tests/mochitest/elm/test_HTMLSpec.html
@@ -1212,17 +1212,17 @@
         absentAttributes: { "xml-roles": "region" },
         interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
       };
       testElm("section", obj);
 
       // HTML:section with an accessible name
 
       obj = {
-        role: ROLE_SECTION,
+        role: ROLE_LANDMARK,
         attributes: { "xml-roles": "region" },
         interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
       };
       testElm("named_section", obj);
 
       // ////////////////////////////////////////////////////////////////////////
       // HTML:small contained by paragraph
 
--- a/accessible/tests/mochitest/role/test_aria.html
+++ b/accessible/tests/mochitest/role/test_aria.html
@@ -52,19 +52,19 @@
       testRole("aria_menuitemradio", ROLE_RADIO_MENU_ITEM);
       testRole("aria_note", ROLE_NOTE);
       testRole("aria_paragraph", ROLE_PARAGRAPH);
       testRole("aria_presentation", ROLE_TEXT); // weak role
       testRole("aria_progressbar", ROLE_PROGRESSBAR);
       testRole("aria_radio", ROLE_RADIOBUTTON);
       testRole("aria_radiogroup", ROLE_RADIO_GROUP);
       testRole("aria_region_no_name", ROLE_TEXT);
-      testRole("aria_region_has_label", ROLE_REGION);
-      testRole("aria_region_has_labelledby", ROLE_REGION);
-      testRole("aria_region_has_title", ROLE_REGION);
+      testRole("aria_region_has_label", ROLE_LANDMARK);
+      testRole("aria_region_has_labelledby", ROLE_LANDMARK);
+      testRole("aria_region_has_title", ROLE_LANDMARK);
       testRole("aria_region_empty_name", ROLE_TEXT);
       testRole("aria_row", ROLE_ROW);
       testRole("aria_rowheader", ROLE_ROWHEADER);
       testRole("aria_scrollbar", ROLE_SCROLLBAR);
       testRole("aria_searchbox", ROLE_ENTRY);
       testRole("aria_separator", ROLE_SEPARATOR);
       testRole("aria_slider", ROLE_SLIDER);
       testRole("aria_spinbutton", ROLE_SPINBUTTON);
--- a/devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_expand.js
+++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_expand.js
@@ -3,27 +3,20 @@
 
 "use strict";
 
 const TEST_FILE = "test-network-request.html";
 const TEST_PATH = "https://example.com/browser/devtools/client/webconsole/" +
                   "test/mochitest/";
 const TEST_URI = TEST_PATH + TEST_FILE;
 
-const NET_PREF = "devtools.webconsole.filter.net";
-const XHR_PREF = "devtools.webconsole.filter.netxhr";
-
 requestLongerTimeout(2);
 
-Services.prefs.setBoolPref(NET_PREF, false);
-Services.prefs.setBoolPref(XHR_PREF, true);
-registerCleanupFunction(() => {
-  Services.prefs.clearUserPref(NET_PREF);
-  Services.prefs.clearUserPref(XHR_PREF);
-});
+pushPref("devtools.webconsole.filter.net", false);
+pushPref("devtools.webconsole.filter.netxhr", true);
 
 const tabs = [{
   id: "headers",
   testEmpty: testEmptyHeaders,
   testContent: testHeaders,
 }, {
   id: "cookies",
   testEmpty: testEmptyCookies,
@@ -50,16 +43,17 @@ const tabs = [{
   testContent: testSecurity,
 }];
 
 /**
  * Main test for checking HTTP logs in the Console panel.
  */
 add_task(async function task() {
   const hud = await openNewTabAndConsole(TEST_URI);
+
   const currentTab = gBrowser.selectedTab;
   const target = await TargetFactory.forTab(currentTab);
 
   // Execute XHR and expand it after all network
   // update events are received. Consequently,
   // check out content of all (HTTP details) tabs.
   await openRequestAfterUpdates(target, hud);
 
@@ -74,86 +68,80 @@ add_task(async function task() {
     await openRequestBeforeUpdates(target, hud, tab);
   }
 });
 
 async function openRequestAfterUpdates(target, hud) {
   const toolbox = gDevTools.getToolbox(target);
 
   const xhrUrl = TEST_PATH + "sjs_slow-response-test-server.sjs";
-  const message = waitForMessage(hud, xhrUrl);
+  const onMessage = waitForMessage(hud, xhrUrl);
+  const onRequestUpdates = waitForRequestUpdates(hud);
+  const onPayloadReady = waitForPayloadReady(hud);
 
   // Fire an XHR POST request.
   ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
     content.wrappedJSObject.testXhrPostSlowResponse();
   });
 
-  const { node: messageNode } = await message;
-
-  info("Network message found.");
+  const { node: messageNode } = await onMessage;
+  ok(messageNode, "Network message found.");
 
-  await waitForRequestUpdates(toolbox);
-
-  const payload = waitForPayloadReady(toolbox);
+  await onRequestUpdates;
 
   // Expand network log
-  const urlNode = messageNode.querySelector(".url");
-  urlNode.click();
+  await expandXhrMessage(messageNode);
 
   const toggleButtonNode = messageNode.querySelector(".sidebar-toggle");
   ok(!toggleButtonNode, "Sidebar toggle button shouldn't be shown");
 
-  await payload;
+  await onPayloadReady;
   await testNetworkMessage(toolbox, messageNode);
 }
 
 async function openRequestBeforeUpdates(target, hud, tab) {
   const toolbox = gDevTools.getToolbox(target);
 
   hud.ui.clearOutput(true);
 
   const xhrUrl = TEST_PATH + "sjs_slow-response-test-server.sjs";
-  const message = waitForMessage(hud, xhrUrl);
+  const onMessage = waitForMessage(hud, xhrUrl);
+  const onRequestUpdates = waitForRequestUpdates(hud);
+  const onPayloadReady = waitForPayloadReady(hud);
 
   // Fire an XHR POST request.
   ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
     content.wrappedJSObject.testXhrPostSlowResponse();
   });
-
-  const { node: messageNode } = await message;
-
-  info("Network message found.");
-
-  const updates = waitForRequestUpdates(toolbox);
-  const payload = waitForPayloadReady(toolbox);
+  const { node: messageNode } = await onMessage;
+  ok(messageNode, "Network message found.");
 
   // Set the default panel.
   const state = hud.ui.consoleOutput.getStore().getState();
   state.ui.networkMessageActiveTabId = tab.id;
 
   // Expand network log
-  const urlNode = messageNode.querySelector(".url");
-  urlNode.click();
+  await expandXhrMessage(messageNode);
 
   // Except the security tab. It isn't available till the
   // "securityInfo" packet type is received, so doesn't
   // fit this part of the test.
   if (tab.id != "security") {
     // Make sure the current tab is the expected one.
     const currentTab = messageNode.querySelector(`#${tab.id}-tab`);
     is(currentTab.getAttribute("aria-selected"), "true",
       "The correct tab is selected");
 
     // The tab should be empty now.
     tab.testEmpty(messageNode);
   }
 
   // Wait till all updates and payload are received.
-  await updates;
-  await payload;
+  await onRequestUpdates;
+  await onPayloadReady;
 
   // Test content of the default tab.
   await tab.testContent(messageNode);
 
   // Test all tabs in the network log.
   await testNetworkMessage(toolbox, messageNode);
 }
 
@@ -186,37 +174,33 @@ function testEmptyHeaders(messageNode) {
 }
 
 async function testHeaders(messageNode) {
   const headersTab = messageNode.querySelector("#headers-tab");
   ok(headersTab, "Headers tab is available");
 
   // Select Headers tab and check the content.
   headersTab.click();
-  await waitUntil(() => {
-    return !!messageNode.querySelector("#headers-panel .headers-overview");
-  });
+  await waitFor(() => messageNode.querySelector("#headers-panel .headers-overview"));
 }
 
 // Cookies
 
 function testEmptyCookies(messageNode) {
   const emptyNotice = messageNode.querySelector("#cookies-panel .empty-notice");
   ok(emptyNotice, "Cookies tab is empty");
 }
 
 async function testCookies(messageNode) {
   const cookiesTab = messageNode.querySelector("#cookies-tab");
   ok(cookiesTab, "Cookies tab is available");
 
   // Select tab and check the content.
   cookiesTab.click();
-  await waitUntil(() => {
-    return !!messageNode.querySelector("#cookies-panel .treeValueCell");
-  });
+  await waitFor(() => messageNode.querySelector("#cookies-panel .treeValueCell"));
 }
 
 // Params
 
 function testEmptyParams(messageNode) {
   const emptyNotice = messageNode.querySelector("#params-panel .empty-notice");
   ok(emptyNotice, "Params tab is empty");
 }
@@ -266,20 +250,18 @@ function testEmptyTimings(messageNode) {
 }
 
 async function testTimings(messageNode) {
   const timingsTab = messageNode.querySelector("#timings-tab");
   ok(timingsTab, "Timings tab is available");
 
   // Select Timings tab and check the content.
   timingsTab.click();
-  await waitUntil(() => {
-    return !!messageNode.querySelector(
-      "#timings-panel .timings-container .timings-label");
-  });
+  await waitFor(() =>
+    messageNode.querySelector("#timings-panel .timings-container .timings-label"));
   const timingsContent = messageNode.querySelector(
     "#timings-panel .timings-container .timings-label");
   ok(timingsContent, "Timings content is available");
   ok(timingsContent.textContent, "Timings text is available");
 }
 
 // Stack Trace
 
@@ -289,65 +271,55 @@ function testEmptyStackTrace(messageNode
 }
 
 async function testStackTrace(messageNode) {
   const stackTraceTab = messageNode.querySelector("#stack-trace-tab");
   ok(stackTraceTab, "StackTrace tab is available");
 
   // Select Timings tab and check the content.
   stackTraceTab.click();
-  await waitUntil(() => {
-    return !!messageNode.querySelector("#stack-trace-panel .frame-link");
-  });
+  await waitFor(() => messageNode.querySelector("#stack-trace-panel .frame-link"));
 }
 
 // Security
 
 function testEmptySecurity(messageNode) {
   const panel = messageNode.querySelector("#security-panel .tab-panel");
   is(panel.textContent, "", "Security tab is empty");
 }
 
 async function testSecurity(messageNode) {
   const securityTab = messageNode.querySelector("#security-tab");
   ok(securityTab, "Security tab is available");
 
   // Select Timings tab and check the content.
   securityTab.click();
-  await waitUntil(() => {
-    return !!messageNode.querySelector("#security-panel .treeTable .treeRow");
-  });
+  await waitFor(() => messageNode.querySelector("#security-panel .treeTable .treeRow"));
 }
 
 // Waiting helpers
 
-async function waitForPayloadReady(toolbox) {
-  const {ui} = toolbox.getCurrentPanel().hud;
-  return new Promise(resolve => {
-    ui.jsterm.hud.on("network-request-payload-ready", () => {
-      info("network-request-payload-ready received");
-      resolve();
-    });
-  });
+async function waitForPayloadReady(hud) {
+  return hud.ui.once("network-request-payload-ready");
 }
 
 async function waitForSourceEditor(panel) {
   return waitUntil(() => {
     return !!panel.querySelector(".CodeMirror");
   });
 }
 
-async function waitForRequestUpdates(toolbox) {
-  const {ui} = toolbox.getCurrentPanel().hud;
-  return new Promise(resolve => {
-    ui.jsterm.hud.on("network-message-updated", () => {
-      info("network-message-updated received");
-      resolve();
-    });
-  });
+async function waitForRequestUpdates(hud) {
+  return hud.ui.once("network-message-updated");
+}
+
+function expandXhrMessage(node) {
+  info("Click on XHR message and wait for the network detail panel to be displayed");
+  node.querySelector(".url").click();
+  return waitFor(() => node.querySelector(".network-info"));
 }
 
 /**
  * Wait until all lazily fetch requests in netmonitor get finished.
  * Otherwise test will be shutdown too early and cause failure.
  */
 async function waitForLazyRequests(toolbox) {
   const {ui} = toolbox.getCurrentPanel().hud;
--- a/widget/windows/ToastNotificationHandler.cpp
+++ b/widget/windows/ToastNotificationHandler.cpp
@@ -393,28 +393,31 @@ ToastNotificationHandler::CreateWindowsN
   return true;
 }
 
 HRESULT
 ToastNotificationHandler::OnActivate(IToastNotification *notification,
                                      IInspectable *inspectable)
 {
   if (mAlertListener) {
-    ComPtr<IToastActivatedEventArgs> eventArgs;
-    HRESULT hr = inspectable->QueryInterface(__uuidof(IToastActivatedEventArgs),
-                                           (void**)&eventArgs);
     nsAutoString argString;
-    if (SUCCEEDED(hr)) {
-      HSTRING arguments;
-      hr = eventArgs->get_Arguments(&arguments);
+    if (inspectable) {
+      ComPtr<IToastActivatedEventArgs> eventArgs;
+      HRESULT hr = inspectable->QueryInterface(
+                     __uuidof(IToastActivatedEventArgs),
+                     (void**)&eventArgs);
       if (SUCCEEDED(hr)) {
-        uint32_t len = 0;
-        const wchar_t* buffer = WindowsGetStringRawBuffer(arguments, &len);
-        if (buffer) {
-          argString.Assign(buffer, len);
+        HSTRING arguments;
+        hr = eventArgs->get_Arguments(&arguments);
+        if (SUCCEEDED(hr)) {
+          uint32_t len = 0;
+          const wchar_t* buffer = WindowsGetStringRawBuffer(arguments, &len);
+          if (buffer) {
+            argString.Assign(buffer, len);
+          }
         }
       }
     }
 
     if (argString.EqualsLiteral("settings")) {
       mAlertListener->Observe(nullptr, "alertsettingscallback", mCookie.get());
     } else if (argString.EqualsLiteral("snooze")) {
       mAlertListener->Observe(nullptr, "alertdisablecallback", mCookie.get());