Merge autoland to mozilla-central. a=merge
authorAndreea Pavel <apavel@mozilla.com>
Tue, 14 Aug 2018 19:14:28 +0300
changeset 486468 cfadc4196e56392680bf53a81740ecdb74976d30
parent 486451 a62c083163d60a523e2d3cae38c6b1a8adac0817 (current diff)
parent 486467 07bf059b54930e579c660cfb7434cb37f3dd3582 (diff)
child 486502 48a45df79f328c88f0ffe0d2aeeb7d78c007d86b
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone63.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
Merge autoland to mozilla-central. a=merge
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,2 @@
 For a full list of the people who are credited with making a
-contribution to Mozilla, see http://www.mozilla.org/credits/ .
+contribution to Mozilla, see https://www.mozilla.org/credits/ .
--- a/devtools/client/framework/selection.js
+++ b/devtools/client/framework/selection.js
@@ -261,9 +261,13 @@ Selection.prototype = {
 
   isNotationNode: function() {
     return this.isNode() && this.nodeFront.nodeType == nodeConstants.NOTATION_NODE;
   },
 
   isSlotted: function() {
     return this._isSlotted;
   },
+
+  isShadowRootNode: function() {
+    return this.isNode() && this.nodeFront.isShadowRoot;
+  },
 };
--- a/devtools/client/inspector/breadcrumbs.js
+++ b/devtools/client/inspector/breadcrumbs.js
@@ -16,16 +16,18 @@ const NS_XHTML = "http://www.w3.org/1999
 const SCROLL_REPEAT_MS = 100;
 
 const EventEmitter = require("devtools/shared/event-emitter");
 const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
 
 // Some margin may be required for visible element detection.
 const SCROLL_MARGIN = 1;
 
+const SHADOW_ROOT_TAGNAME = "#shadow-root";
+
 /**
  * Component to replicate functionality of XUL arrowscrollbox
  * for breadcrumbs
  *
  * @param {Window} win The window containing the breadcrumbs
  * @parem {DOMNode} container The element in which to put the scroll box
  */
 function ArrowScrollBox(win, container) {
@@ -412,17 +414,17 @@ HTMLBreadcrumbs.prototype = {
 
   /**
 
    * Build a string that represents the node: tagName#id.class1.class2.
    * @param {NodeFront} node The node to pretty-print
    * @return {String}
    */
   prettyPrintNodeAsText: function(node) {
-    let text = node.displayName;
+    let text = node.isShadowRoot ? SHADOW_ROOT_TAGNAME : node.displayName;
     if (node.isPseudoElement) {
       text = node.isBeforePseudoElement ? "::before" : "::after";
     }
 
     if (node.id) {
       text += "#" + node.id;
     }
 
@@ -456,17 +458,17 @@ HTMLBreadcrumbs.prototype = {
     idLabel.className = "breadcrumbs-widget-item-id plain";
 
     const classesLabel = this.doc.createElementNS(NS_XHTML, "span");
     classesLabel.className = "breadcrumbs-widget-item-classes plain";
 
     const pseudosLabel = this.doc.createElementNS(NS_XHTML, "span");
     pseudosLabel.className = "breadcrumbs-widget-item-pseudo-classes plain";
 
-    let tagText = node.displayName;
+    let tagText = node.isShadowRoot ? SHADOW_ROOT_TAGNAME : node.displayName;
     if (node.isPseudoElement) {
       tagText = node.isBeforePseudoElement ? "::before" : "::after";
     }
     let idText = node.id ? ("#" + node.id) : "";
     let classesText = "";
 
     if (node.className) {
       const classList = node.className.split(/\s+/);
@@ -724,17 +726,17 @@ HTMLBreadcrumbs.prototype = {
     const fragment = this.doc.createDocumentFragment();
     let lastButtonInserted = null;
     const originalLength = this.nodeHierarchy.length;
     let stopNode = null;
     if (originalLength > 0) {
       stopNode = this.nodeHierarchy[originalLength - 1].node;
     }
     while (node && node != stopNode) {
-      if (node.tagName) {
+      if (node.tagName || node.isShadowRoot) {
         const button = this.buildButton(node);
         fragment.insertBefore(button, lastButtonInserted);
         lastButtonInserted = button;
         this.nodeHierarchy.splice(originalLength, 0, {
           node,
           button,
           currentPrettyPrintText: this.prettyPrintNodeAsText(node)
         });
@@ -875,17 +877,17 @@ HTMLBreadcrumbs.prototype = {
           if (removedIndex > -1) {
             this.cutAfter(removedIndex - 1);
             trimmed = true;
           }
         }
       }
     }
 
-    if (!this.selection.isElementNode()) {
+    if (!this.selection.isElementNode() && !this.selection.isShadowRootNode()) {
       // no selection
       this.setCursor(-1);
       if (trimmed) {
         // Since something changed, notify the interested parties.
         this.inspector.emit("breadcrumbs-updated", this.selection.nodeFront);
       }
       return;
     }
--- a/devtools/client/inspector/test/browser_inspector_breadcrumbs_shadowdom.js
+++ b/devtools/client/inspector/test/browser_inspector_breadcrumbs_shadowdom.js
@@ -43,17 +43,17 @@ add_task(async function() {
 
   info("Select the slot node and wait for the breadcrumbs update");
   const slotNodeFront = slotContainer.node;
   let onBreadcrumbsUpdated = inspector.once("breadcrumbs-updated");
   inspector.selection.setNodeFront(slotNodeFront);
   await onBreadcrumbsUpdated;
 
   checkBreadcrumbsContent(breadcrumbs,
-    ["html", "body", "test-component", "slot.slot-class"]);
+    ["html", "body", "test-component", "#shadow-root", "slot.slot-class"]);
 
   info("Expand the slot");
   await expandContainer(inspector, slotContainer);
 
   const slotChildContainers = slotContainer.getChildContainers();
   is(slotChildContainers.length, 1, "Expecting 1 slotted child");
 
   info("Select the slotted node and wait for the breadcrumbs update");
--- a/devtools/client/netmonitor/src/api.js
+++ b/devtools/client/netmonitor/src/api.js
@@ -7,16 +7,19 @@
 const EventEmitter = require("devtools/shared/event-emitter");
 
 const { bindActionCreators } = require("devtools/client/shared/vendor/redux");
 const { Connector } = require("./connector/index");
 const { configureStore } = require("./create-store");
 const { EVENTS } = require("./constants");
 const Actions = require("./actions/index");
 
+// Telemetry
+const Telemetry = require("devtools/client/shared/telemetry");
+
 const {
   getDisplayedRequestById,
   getSortedRequests
 } = require("./selectors/index");
 
 /**
  * API object for NetMonitor panel (like a facade). This object can be
  * consumed by other panels, WebExtension API, etc.
@@ -25,18 +28,21 @@ const {
  * and used even if the Network panel UI doesn't exist.
  */
 function NetMonitorAPI() {
   EventEmitter.decorate(this);
 
   // Connector to the backend.
   this.connector = new Connector();
 
+  // Telemetry
+  this.telemetry = new Telemetry();
+
   // Configure store/state object.
-  this.store = configureStore(this.connector);
+  this.store = configureStore(this.connector, this.telemetry);
 
   // List of listeners for `devtools.network.onRequestFinished` WebExt API
   this._requestFinishedListeners = new Set();
 
   // Bind event handlers
   this.onRequestAdded = this.onRequestAdded.bind(this);
   this.actions = bindActionCreators(Actions, this.store.dispatch);
 }
--- a/devtools/client/netmonitor/src/create-store.js
+++ b/devtools/client/netmonitor/src/create-store.js
@@ -8,29 +8,30 @@ const Services = require("Services");
 const { applyMiddleware, createStore } = require("devtools/client/shared/vendor/redux");
 
 // Middleware
 const batching = require("./middleware/batching");
 const prefs = require("./middleware/prefs");
 const thunk = require("./middleware/thunk");
 const recording = require("./middleware/recording");
 const throttling = require("./middleware/throttling");
+const eventTelemetry = require("./middleware/event-telemetry");
 
 // Reducers
 const rootReducer = require("./reducers/index");
 const { FilterTypes, Filters } = require("./reducers/filters");
 const { Requests } = require("./reducers/requests");
 const { Sort } = require("./reducers/sort");
 const { TimingMarkers } = require("./reducers/timing-markers");
 const { UI, Columns } = require("./reducers/ui");
 
 /**
  * Configure state and middleware for the Network monitor tool.
  */
-function configureStore(connector) {
+function configureStore(connector, telemetry) {
   // Prepare initial state.
   const initialState = {
     filters: new Filters({
       requestFilterTypes: getFilterState()
     }),
     requests: new Requests(),
     sort: new Sort(),
     timingMarkers: new TimingMarkers(),
@@ -41,16 +42,17 @@ function configureStore(connector) {
 
   // Prepare middleware.
   const middleware = applyMiddleware(
     thunk,
     prefs,
     batching,
     recording(connector),
     throttling(connector),
+    eventTelemetry(connector, telemetry),
   );
 
   return createStore(rootReducer, initialState, middleware);
 }
 
 // Helpers
 
 /**
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/middleware/event-telemetry.js
@@ -0,0 +1,86 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { gDevTools } = require("devtools/client/framework/devtools");
+
+const {
+  TOGGLE_REQUEST_FILTER_TYPE,
+  ENABLE_REQUEST_FILTER_TYPE_ONLY,
+  SET_REQUEST_FILTER_TEXT,
+} = require("../constants");
+
+/**
+ * Event telemetry middleware is responsible for logging
+ * specific filter events to telemetry. This telemetry
+ * helps to track Net panel filtering usage.
+ */
+function eventTelemetryMiddleware(connector, telemetry) {
+  return store => next => action => {
+    const oldState = store.getState();
+    const res = next(action);
+    const toolbox = gDevTools.getToolbox(connector.getTabTarget());
+    if (!toolbox) {
+      return res;
+    }
+
+    const state = store.getState();
+
+    const filterChangeActions = [
+      TOGGLE_REQUEST_FILTER_TYPE,
+      ENABLE_REQUEST_FILTER_TYPE_ONLY,
+      SET_REQUEST_FILTER_TEXT,
+    ];
+
+    if (filterChangeActions.includes(action.type)) {
+      filterChange({
+        action,
+        state,
+        oldState,
+        telemetry,
+        sessionId: toolbox.sessionId,
+      });
+    }
+
+    return res;
+  };
+}
+
+function filterChange({action, state, oldState, telemetry, sessionId}) {
+  const oldFilterState = oldState.filters;
+  const filterState = state.filters;
+  const activeFilters = [];
+  const inactiveFilters = [];
+
+  for (const [key, value] of Object.entries(filterState.requestFilterTypes)) {
+    if (value) {
+      activeFilters.push(key);
+    } else {
+      inactiveFilters.push(key);
+    }
+  }
+
+  let trigger;
+  if (action.type === TOGGLE_REQUEST_FILTER_TYPE ||
+      action.type === ENABLE_REQUEST_FILTER_TYPE_ONLY) {
+    trigger = action.filter;
+  } else if (action.type === SET_REQUEST_FILTER_TEXT) {
+    if (oldFilterState.requestFilterText !== "" &&
+        filterState.requestFilterText !== "") {
+      return;
+    }
+
+    trigger = "text";
+  }
+
+  telemetry.recordEvent("devtools.main", "filters_changed", "netmonitor", null, {
+    "trigger": trigger,
+    "active": activeFilters.join(","),
+    "inactive": inactiveFilters.join(","),
+    "session_id": sessionId
+  });
+}
+
+module.exports = eventTelemetryMiddleware;
--- a/devtools/client/netmonitor/src/middleware/moz.build
+++ b/devtools/client/netmonitor/src/middleware/moz.build
@@ -1,11 +1,12 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DevToolsModules(
     'batching.js',
+    'event-telemetry.js',
     'prefs.js',
     'recording.js',
     'throttling.js',
     'thunk.js',
 )
--- a/devtools/client/netmonitor/test/browser.ini
+++ b/devtools/client/netmonitor/test/browser.ini
@@ -180,15 +180,16 @@ skip-if = true # Bug 1258809
 [browser_net_sort-01.js]
 [browser_net_sort-02.js]
 [browser_net_statistics-01.js]
 skip-if = true # Bug 1373558
 [browser_net_statistics-02.js]
 [browser_net_status-bar.js]
 [browser_net_status-codes.js]
 [browser_net_streaming-response.js]
+[browser_net_telemetry_filters_changed.js]
 [browser_net_throttle.js]
 [browser_net_timeline_ticks.js]
 skip-if = true # TODO: fix the test
 [browser_net_timing-division.js]
 [browser_net_truncate.js]
 [browser_net_view-source-debugger.js]
 [browser_net_waterfall-click.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/test/browser_net_telemetry_filters_changed.js
@@ -0,0 +1,109 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
+
+/**
+ * Test the filters_changed telemetry event.
+ */
+add_task(async function() {
+  const { tab, monitor } = await initNetMonitor(SIMPLE_URL);
+  info("Starting test... ");
+
+  const { document, store, windowRequire } = monitor.panelWin;
+  const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
+  const {
+    getDisplayedRequests,
+  } = windowRequire("devtools/client/netmonitor/src/selectors/index");
+
+  store.dispatch(Actions.batchEnable(false));
+
+  // Remove all telemetry events (you can check about:telemetry).
+  Services.telemetry.clearEvents();
+
+  // Ensure no events have been logged
+  const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
+  ok(!snapshot.parent, "No events have been logged for the main process");
+
+  // Reload to have one request in the list.
+  const wait = waitForNetworkEvents(monitor, 1);
+  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  await wait;
+
+  info("Click on the 'HTML' filter");
+  EventUtils.sendMouseEvent({ type: "click" },
+    document.querySelector(".requests-list-filter-html-button"));
+
+  checkTelemetryEvent({
+    trigger: "html",
+    active: "html",
+    inactive: "all,css,js,xhr,fonts,images,media,ws,other",
+  });
+
+  info("Click on the 'CSS' filter");
+  EventUtils.sendMouseEvent({ type: "click" },
+    document.querySelector(".requests-list-filter-css-button"));
+
+  checkTelemetryEvent({
+    trigger: "css",
+    active: "html,css",
+    inactive: "all,js,xhr,fonts,images,media,ws,other",
+  });
+
+  info("Filter the output using the text filter input");
+  setFreetextFilter(monitor, "nomatch");
+
+  // Wait till the text filter is applied.
+  await waitUntil(() => getDisplayedRequests(store.getState()).length == 0);
+
+  checkTelemetryEvent({
+    trigger: "text",
+    active: "html,css",
+    inactive: "all,js,xhr,fonts,images,media,ws,other",
+  });
+
+  return teardown(monitor);
+});
+
+function setFreetextFilter(monitor, value) {
+  const { document } = monitor.panelWin;
+
+  const filterBox = document.querySelector(".devtools-filterinput");
+  filterBox.focus();
+  filterBox.value = "";
+
+  for (const ch of value) {
+    EventUtils.synthesizeKey(ch, {}, monitor.panelWin);
+  }
+}
+
+function checkTelemetryEvent(expectedEvent) {
+  const events = getFiltersChangedEventsExtra();
+  is(events.length, 1, "There was only 1 event logged");
+  const [event] = events;
+  ok(event.session_id > 0, "There is a valid session_id in the logged event");
+  const f = e => JSON.stringify(e, null, 2);
+  is(f(event), f({
+    ...expectedEvent,
+    "session_id": event.session_id
+  }), "The event has the expected data");
+}
+
+function getFiltersChangedEventsExtra() {
+  // Retrieve and clear telemetry events.
+  const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
+
+  const filtersChangedEvents = snapshot.parent.filter(event =>
+    event[1] === "devtools.main" &&
+    event[2] === "filters_changed" &&
+    event[3] === "netmonitor"
+  );
+
+  // Since we already know we have the correct event, we only return the `extra` field
+  // that was passed to it (which is event[5] here).
+  return filtersChangedEvents.map(event => event[5]);
+}
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1625,17 +1625,17 @@ nsFocusManager::CheckIfFocusable(Element
   }
 
   // if this is a child frame content node, check if it is visible and
   // call the content node's IsFocusable method instead of the frame's
   // IsFocusable method. This skips checking the style system and ensures that
   // offscreen browsers can still be focused.
   nsIDocument* subdoc = doc->GetSubDocumentFor(aElement);
   if (subdoc && IsWindowVisible(subdoc->GetWindow())) {
-    const nsStyleUserInterface* ui = frame->StyleUserInterface();
+    const nsStyleUI* ui = frame->StyleUI();
     int32_t tabIndex = (ui->mUserFocus == StyleUserFocus::Ignore ||
                         ui->mUserFocus == StyleUserFocus::None) ? -1 : 0;
     return aElement->IsFocusable(&tabIndex, aFlags & FLAG_BYMOUSE) ? aElement : nullptr;
   }
 
   return frame->IsFocusable(nullptr, aFlags & FLAG_BYMOUSE) ? aElement : nullptr;
 }
 
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3186,17 +3186,17 @@ EventStateManager::PostHandleEvent(nsPre
       // nsEventStatus_eIgnore in EventStateManager::PreHandleEvent. So we also
       // check if the event is DefaultPrevented.
       if (nsEventStatus_eConsumeNoDefault != *aStatus &&
           !aEvent->DefaultPrevented()) {
         nsCOMPtr<nsIContent> newFocus;
         bool suppressBlur = false;
         if (mCurrentTarget) {
           mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(newFocus));
-          const nsStyleUserInterface* ui = mCurrentTarget->StyleUserInterface();
+          const nsStyleUI* ui = mCurrentTarget->StyleUI();
           activeContent = mCurrentTarget->GetContent();
 
           // In some cases, we do not want to even blur the current focused
           // element. Those cases are:
           // 1. -moz-user-focus CSS property is set to 'ignore';
           // 2. Element with NS_EVENT_STATE_DISABLED
           //    (aka :disabled pseudo-class for HTML element);
           // 3. XUL control element has the disabled property set to 'true'.
@@ -5216,17 +5216,17 @@ EventStateManager::SetContentState(nsICo
   if (aState == NS_EVENT_STATE_HOVER || aState == NS_EVENT_STATE_ACTIVE) {
     // Hover and active are hierarchical
     updateAncestors = true;
 
     // check to see that this state is allowed by style. Check dragover too?
     // XXX Is this even what we want?
     if (mCurrentTarget)
     {
-      const nsStyleUserInterface* ui = mCurrentTarget->StyleUserInterface();
+      const nsStyleUI* ui = mCurrentTarget->StyleUI();
       if (ui->mUserInput == StyleUserInput::None) {
         return false;
       }
     }
 
     if (aState == NS_EVENT_STATE_ACTIVE) {
       // Editable content can never become active since their default actions
       // are disabled.  Watch out for editable content in native anonymous
--- a/dom/html/HTMLOptGroupElement.cpp
+++ b/dom/html/HTMLOptGroupElement.cpp
@@ -48,17 +48,17 @@ HTMLOptGroupElement::GetEventTargetParen
   // XXXsmaug This is not the right thing to do. But what is?
   if (IsDisabled()) {
     return;
   }
 
   if (nsIFrame* frame = GetPrimaryFrame()) {
     // FIXME(emilio): This poking at the style of the frame is broken unless we
     // flush before every event handling, which we don't really want to.
-    if (frame->StyleUserInterface()->mUserInput == StyleUserInput::None) {
+    if (frame->StyleUI()->mUserInput == StyleUserInput::None) {
       return;
     }
   }
 
   nsGenericHTMLElement::GetEventTargetParent(aVisitor);
 }
 
 Element*
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -2175,18 +2175,17 @@ nsGenericHTMLFormElement::IsElementDisab
     case eLegacyMousePixelScroll:
       return false;
     default:
       break;
   }
 
   // FIXME(emilio): This poking at the style of the frame is slightly bogus
   // unless we flush before every event, which we don't really want to do.
-  if (aFrame &&
-      aFrame->StyleUserInterface()->mUserInput == StyleUserInput::None) {
+  if (aFrame && aFrame->StyleUI()->mUserInput == StyleUserInput::None) {
     return true;
   }
 
   return IsDisabled();
 }
 
 void
 nsGenericHTMLFormElement::UpdateFormOwner(bool aBindToTree,
--- a/dom/serviceworkers/ServiceWorkerManager.cpp
+++ b/dom/serviceworkers/ServiceWorkerManager.cpp
@@ -3,31 +3,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ServiceWorkerManager.h"
 
 #include "nsAutoPtr.h"
 #include "nsIConsoleService.h"
-#include "nsIDocument.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIStreamLoader.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIHttpHeaderVisitor.h"
 #include "nsINamed.h"
 #include "nsINetworkInterceptController.h"
 #include "nsIMutableArray.h"
 #include "nsIScriptError.h"
 #include "nsISimpleEnumerator.h"
 #include "nsITimer.h"
 #include "nsIUploadChannel2.h"
-#include "nsPIDOMWindow.h"
 #include "nsServiceManagerUtils.h"
 #include "nsDebug.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIPermissionManager.h"
 
 #include "jsapi.h"
 
 #include "mozilla/BasePrincipal.h"
@@ -1229,36 +1227,16 @@ ServiceWorkerManager::GetActiveWorkerInf
     GetServiceWorkerRegistrationInfo(principal, scopeURI);
   if (!registration) {
     return nullptr;
   }
 
   return registration->GetActive();
 }
 
-ServiceWorkerInfo*
-ServiceWorkerManager::GetActiveWorkerInfoForDocument(nsIDocument* aDocument)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  Maybe<ClientInfo> clientInfo(aDocument->GetClientInfo());
-  if (clientInfo.isNothing()) {
-    return nullptr;
-  }
-
-  RefPtr<ServiceWorkerRegistrationInfo> registration;
-  GetClientRegistration(clientInfo.ref(), getter_AddRefs(registration));
-
-  if (!registration) {
-    return nullptr;
-  }
-
-  return registration->GetActive();
-}
-
 namespace {
 
 class UnregisterJobCallback final : public ServiceWorkerJob::Callback
 {
   nsCOMPtr<nsIServiceWorkerUnregisterCallback> mCallback;
 
   ~UnregisterJobCallback()
   {
@@ -1626,41 +1604,16 @@ ServiceWorkerManager::StoreRegistration(
                                                     &principalInfo)))) {
     return;
   }
 
   mActor->SendRegister(data);
 }
 
 already_AddRefed<ServiceWorkerRegistrationInfo>
-ServiceWorkerManager::GetServiceWorkerRegistrationInfo(nsPIDOMWindowInner* aWindow) const
-{
-  MOZ_ASSERT(aWindow);
-  nsCOMPtr<nsIDocument> document = aWindow->GetExtantDoc();
-  return GetServiceWorkerRegistrationInfo(document);
-}
-
-already_AddRefed<ServiceWorkerRegistrationInfo>
-ServiceWorkerManager::GetServiceWorkerRegistrationInfo(nsIDocument* aDoc) const
-{
-  MOZ_ASSERT(aDoc);
-  nsCOMPtr<nsIURI> documentURI = aDoc->GetDocumentURI();
-  nsCOMPtr<nsIPrincipal> principal = aDoc->NodePrincipal();
-  RefPtr<ServiceWorkerRegistrationInfo> reg =
-    GetServiceWorkerRegistrationInfo(principal, documentURI);
-  if (reg) {
-    auto storageAllowed = nsContentUtils::StorageAllowedForDocument(aDoc);
-    if (storageAllowed != nsContentUtils::StorageAccess::eAllow) {
-      reg = nullptr;
-    }
-  }
-  return reg.forget();
-}
-
-already_AddRefed<ServiceWorkerRegistrationInfo>
 ServiceWorkerManager::GetServiceWorkerRegistrationInfo(const ClientInfo& aClientInfo) const
 {
   nsCOMPtr<nsIPrincipal> principal = aClientInfo.GetPrincipal();
   NS_ENSURE_TRUE(principal, nullptr);
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), aClientInfo.URL(),
                           nullptr, nullptr);
--- a/dom/serviceworkers/ServiceWorkerManager.h
+++ b/dom/serviceworkers/ServiceWorkerManager.h
@@ -373,29 +373,20 @@ private:
   nsresult
   GetClientRegistration(const ClientInfo& aClientInfo,
                         ServiceWorkerRegistrationInfo** aRegistrationInfo);
 
   ServiceWorkerInfo*
   GetActiveWorkerInfoForScope(const OriginAttributes& aOriginAttributes,
                               const nsACString& aScope);
 
-  ServiceWorkerInfo*
-  GetActiveWorkerInfoForDocument(nsIDocument* aDocument);
-
   void
   StopControllingRegistration(ServiceWorkerRegistrationInfo* aRegistration);
 
   already_AddRefed<ServiceWorkerRegistrationInfo>
-  GetServiceWorkerRegistrationInfo(nsPIDOMWindowInner* aWindow) const;
-
-  already_AddRefed<ServiceWorkerRegistrationInfo>
-  GetServiceWorkerRegistrationInfo(nsIDocument* aDoc) const;
-
-  already_AddRefed<ServiceWorkerRegistrationInfo>
   GetServiceWorkerRegistrationInfo(const ClientInfo& aClientInfo) const;
 
   already_AddRefed<ServiceWorkerRegistrationInfo>
   GetServiceWorkerRegistrationInfo(nsIPrincipal* aPrincipal, nsIURI* aURI) const;
 
   already_AddRefed<ServiceWorkerRegistrationInfo>
   GetServiceWorkerRegistrationInfo(const nsACString& aScopeKey,
                                    nsIURI* aURI) const;
--- a/dom/xul/nsXULPopupListener.cpp
+++ b/dom/xul/nsXULPopupListener.cpp
@@ -200,17 +200,17 @@ nsXULPopupListener::FireFocusOnTargetCon
   RefPtr<nsPresContext> context = doc->GetPresContext();
   if (!context) {
     return NS_ERROR_FAILURE;
   }
 
   nsIFrame* targetFrame = aTargetContent->GetPrimaryFrame();
   if (!targetFrame) return NS_ERROR_FAILURE;
 
-  const nsStyleUserInterface* ui = targetFrame->StyleUserInterface();
+  const nsStyleUI* ui = targetFrame->StyleUI();
   bool suppressBlur = (ui->mUserFocus == StyleUserFocus::Ignore);
 
   RefPtr<Element> newFocusElement;
 
   nsIFrame* currFrame = targetFrame;
   // Look for the nearest enclosing focusable frame.
   while (currFrame) {
     int32_t tabIndexUnused;
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -1726,37 +1726,61 @@ HTMLEditor::InsertNodeIntoProperAncestor
     }
   }
   return pointToInsert;
 }
 
 NS_IMETHODIMP
 HTMLEditor::SelectElement(Element* aElement)
 {
+  if (NS_WARN_IF(!aElement)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  RefPtr<Selection> selection = GetSelection();
+  if (NS_WARN_IF(!selection)) {
+    return NS_ERROR_FAILURE;
+  }
+  nsresult rv = SelectContentInternal(*selection, *aElement);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
+}
+
+nsresult
+HTMLEditor::SelectContentInternal(Selection& aSelection,
+                                  nsIContent& aContentToSelect)
+{
   // Must be sure that element is contained in the document body
-  if (!IsDescendantOfEditorRoot(aElement)) {
-    return NS_ERROR_NULL_POINTER;
-  }
-
-  RefPtr<Selection> selection = GetSelection();
-  NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
-  nsINode* parent = aElement->GetParentNode();
+  if (!IsDescendantOfEditorRoot(&aContentToSelect)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsINode* parent = aContentToSelect.GetParentNode();
   if (NS_WARN_IF(!parent)) {
     return NS_ERROR_FAILURE;
   }
 
-  int32_t offsetInParent = parent->ComputeIndexOf(aElement);
+  // Don't notify selection change at collapse.
+  AutoUpdateViewBatch notifySelectionChangeOnce(this);
+
+  // XXX Perhaps, Selection should have SelectNode(nsIContent&).
+  int32_t offsetInParent = parent->ComputeIndexOf(&aContentToSelect);
 
   // Collapse selection to just before desired element,
-  nsresult rv = selection->Collapse(parent, offsetInParent);
-  if (NS_SUCCEEDED(rv)) {
-    // then extend it to just after
-    rv = selection->Extend(parent, offsetInParent + 1);
-  }
-  return rv;
+  nsresult rv = aSelection.Collapse(parent, offsetInParent);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  // then extend it to just after
+  rv = aSelection.Extend(parent, offsetInParent + 1);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::SetCaretAfterElement(Element* aElement)
 {
   // Be sure the element is contained in the document body
   if (!aElement || !IsDescendantOfEditorRoot(aElement)) {
     return NS_ERROR_NULL_POINTER;
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -767,16 +767,27 @@ protected: // Called by helper classes.
   virtual void OnEndHandlingTopLevelEditSubAction() override;
 
 protected: // Shouldn't be used by friend classes
   virtual ~HTMLEditor();
 
   virtual nsresult SelectAllInternal() override;
 
   /**
+   * SelectContentInternal() sets Selection to aContentToSelect to
+   * aContentToSelect + 1 in parent of aContentToSelect.
+   *
+   * @param aSelection          The Selection, callers have to guarantee the
+   *                            lifetime.
+   * @param aContentToSelect    The content which should be selected.
+   */
+  nsresult SelectContentInternal(Selection& aSelection,
+                                 nsIContent& aContentToSelect);
+
+  /**
    * PasteInternal() pasts text with replacing selected content.
    * This tries to dispatch ePaste event first.  If its defaultPrevent() is
    * called, this does nothing but returns NS_OK.
    *
    * @param aClipboardType  nsIClipboard::kGlobalClipboard or
    *                        nsIClipboard::kSelectionClipboard.
    */
   nsresult PasteInternal(int32_t aClipboardType);
--- a/editor/libeditor/HTMLTableEditor.cpp
+++ b/editor/libeditor/HTMLTableEditor.cpp
@@ -3070,17 +3070,19 @@ HTMLEditor::SetSelectionAfterTableEdit(E
     nsresult rv = GetCellAt(aTable, aRow, aCol, getter_AddRefs(cell));
     if (NS_FAILED(rv)) {
       break;
     }
 
     if (cell) {
       if (aSelected) {
         // Reselect the cell
-        SelectElement(cell);
+        DebugOnly<nsresult> rv = SelectContentInternal(*selection, *cell);
+        NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
+          "Failed to select the cell");
         return;
       }
 
       // Set the caret to deepest first child
       //   but don't go into nested tables
       // TODO: Should we really be placing the caret at the END
       //  of the cell content?
       CollapseSelectionToDeepestNonTableFirstChild(selection, cell);
--- a/editor/libeditor/tests/mochitest.ini
+++ b/editor/libeditor/tests/mochitest.ini
@@ -276,16 +276,17 @@ subsuite = clipboard
 skip-if = android_version == '24'
 [test_inline_style_cache.html]
 [test_inlineTableEditing.html]
 [test_insertParagraph_in_inline_editing_host.html]
 [test_keypress_untrusted_event.html]
 [test_middle_click_paste.html]
 subsuite = clipboard
 skip-if = android_version == '24'
+[test_nsIHTMLEditor_selectElement.html]
 [test_objectResizing.html]
 [test_root_element_replacement.html]
 [test_select_all_without_body.html]
 [test_spellcheck_pref.html]
 skip-if = toolkit == 'android'
 [test_undo_after_spellchecker_replaces_word.html]
 skip-if = toolkit == 'android'
 [test_undo_redo_stack_after_setting_value.html]
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/tests/test_nsIHTMLEditor_selectElement.html
@@ -0,0 +1,131 @@
+<!DOCTYPE>
+<html>
+<head>
+  <title>Test for nsIHTMLEditor.selectElement()</title>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<div id="display">
+</div>
+<div id="content" contenteditable></div>
+<pre id="test">
+</pre>
+
+<script class="testbody" type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+  let editor = document.getElementById("content");
+  let selection = window.getSelection();
+
+  editor.innerHTML = "<p>p1<b>b1</b><i>i1</i></p><p><b>b2</b><i>i2</i>p2</p>";
+
+  editor.focus();
+  try {
+    getHTMLEditor().selectElement(editor.firstChild.firstChild);
+    ok(false, "nsIHTMLEditor.selectElement() should throw an exception if given node is not an element");
+  } catch (e) {
+    ok(true, `nsIHTMLEditor.selectElement() should throw an exception if given node is not an element: ${e}`);
+  }
+
+  editor.focus();
+  try {
+    getHTMLEditor().selectElement(editor.firstChild.firstChild.nextSibling);
+    is(selection.anchorNode, editor.firstChild,
+       "nsIHTMLEditor.selectElement() should set anchor node to parent of <b> element in the first paragraph");
+    is(selection.anchorOffset, 1,
+       "nsIHTMLEditor.selectElement() should set anchor offset to the index of <b> element in the first paragraph");
+    is(selection.focusNode, editor.firstChild,
+       "nsIHTMLEditor.selectElement() should set focus node to parent of <b> element in the first paragraph");
+    is(selection.focusOffset, 2,
+       "nsIHTMLEditor.selectElement() should set anchor offset to the index of <b> element + 1 in the first paragraph");
+  } catch (e) {
+    ok(false, `nsIHTMLEditor.selectElement() shouldn't throw exception when selecting an element in focused editor #1: ${e}`);
+  }
+
+  editor.focus();
+  try {
+    getHTMLEditor().selectElement(editor.firstChild.nextSibling.firstChild);
+    is(selection.anchorNode, editor.firstChild.nextSibling,
+       "nsIHTMLEditor.selectElement() should set anchor node to parent of <b> element in the second paragraph");
+    is(selection.anchorOffset, 0,
+       "nsIHTMLEditor.selectElement() should set anchor offset to the index of <b> element in the second paragraph");
+    is(selection.focusNode, editor.firstChild.nextSibling,
+       "nsIHTMLEditor.selectElement() should set focus node to parent of <b> element in the second paragraph");
+    is(selection.focusOffset, 1,
+       "nsIHTMLEditor.selectElement() should set anchor offset to the index of <b> element + 1 in the second paragraph");
+  } catch (e) {
+    ok(false, `nsIHTMLEditor.selectElement() shouldn't throw exception when selecting an element in focused editor #2: ${e}`);
+  }
+
+  editor.focus();
+  try {
+    getHTMLEditor().selectElement(editor);
+    ok(false, "nsIHTMLEditor.selectElement() should throw an exception if given node is the editing host");
+  } catch (e) {
+    ok(true, `nsIHTMLEditor.selectElement() should throw an exception if given node is the editing host: ${e}`);
+  }
+
+  editor.focus();
+  try {
+    getHTMLEditor().selectElement(editor.parentElement);
+    ok(false, "nsIHTMLEditor.selectElement() should throw an exception if given node is outside of the editing host");
+  } catch (e) {
+    ok(true, `nsIHTMLEditor.selectElement() should throw an exception if given node is outside of the editing host: ${e}`);
+  }
+
+  selection.removeAllRanges();
+  editor.blur();
+  try {
+    getHTMLEditor().selectElement(editor.firstChild.nextSibling.firstChild);
+    ok(false, "nsIHTMLEditor.selectElement() should throw an exception if there is no active editing host");
+  } catch (e) {
+    ok(true, `nsIHTMLEditor.selectElement() should throw an exception if there is no active editing host: ${e}`);
+  }
+
+  editor.focus();
+  editor.firstChild.firstChild.nextSibling.nextSibling.setAttribute("contenteditable", "false");
+  try {
+    getHTMLEditor().selectElement(editor.firstChild.firstChild.nextSibling.nextSibling);
+    is(selection.anchorNode, editor.firstChild,
+       "nsIHTMLEditor.selectElement() should set anchor node to parent of <i contenteditable=\"false\"> element in the first paragraph");
+    is(selection.anchorOffset, 2,
+       "nsIHTMLEditor.selectElement() should set anchor offset to the index of <i contenteditable=\"false\"> element in the first paragraph");
+    is(selection.focusNode, editor.firstChild,
+       "nsIHTMLEditor.selectElement() should set focus node to parent of <i contenteditable=\"false\"> element in the first paragraph");
+    is(selection.focusOffset, 3,
+       "nsIHTMLEditor.selectElement() should set anchor offset to the index of <i contenteditable=\"false\"> element + 1 in the first paragraph");
+  } catch (e) {
+    ok(false, `nsIHTMLEditor.selectElement() shouldn't throw exception when selecting an element in focused editor #3: ${e}`);
+  }
+
+  editor.focus();
+  editor.firstChild.nextSibling.setAttribute("contenteditable", "false");
+  try {
+    getHTMLEditor().selectElement(editor.firstChild.nextSibling.firstChild.nextSibling);
+    is(selection.anchorNode, editor.firstChild.nextSibling,
+       "nsIHTMLEditor.selectElement() should set anchor node to parent of <i> element in the second paragraph which is not editable");
+    is(selection.anchorOffset, 1,
+       "nsIHTMLEditor.selectElement() should set anchor offset to the index of <i> element in the second paragraph which is not editable");
+    is(selection.focusNode, editor.firstChild.nextSibling,
+       "nsIHTMLEditor.selectElement() should set focus node to parent of <i> element in the second paragraph which is not editable");
+    is(selection.focusOffset, 2,
+       "nsIHTMLEditor.selectElement() should set anchor offset to the index of <i> element + 1 in the second paragraph which is not editable");
+  } catch (e) {
+    ok(false, `nsIHTMLEditor.selectElement() shouldn't throw exception when selecting an element in focused editor #4: ${e}`);
+  }
+
+  SimpleTest.finish();
+});
+
+function getHTMLEditor() {
+  var Ci = SpecialPowers.Ci;
+  var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
+  return editingSession.getEditorForWindow(window).QueryInterface(Ci.nsIHTMLEditor);
+}
+
+</script>
+</body>
+
+</html>
--- a/layout/base/nsCaret.cpp
+++ b/layout/base/nsCaret.cpp
@@ -505,19 +505,18 @@ nsCaret::GetPaintGeometry(nsRect* aRect)
   int32_t frameOffset;
   nsIFrame* frame = GetFrameAndOffset(GetSelection(),
       mOverrideContent, mOverrideOffset, &frameOffset);
   if (!frame) {
     return nullptr;
   }
 
   // now we have a frame, check whether it's appropriate to show the caret here
-  const nsStyleUserInterface* userinterface = frame->StyleUserInterface();
-  if ((!mIgnoreUserModify &&
-       userinterface->mUserModify == StyleUserModify::ReadOnly) ||
+  const nsStyleUI* ui = frame->StyleUI();
+  if ((!mIgnoreUserModify && ui->mUserModify == StyleUserModify::ReadOnly) ||
       frame->IsContentDisabled()) {
     return nullptr;
   }
 
   // If the offset falls outside of the frame, then don't paint the caret.
   int32_t startOffset, endOffset;
   if (frame->IsTextFrame() &&
       (NS_FAILED(frame->GetOffsets(startOffset, endOffset)) ||
--- a/layout/doc/adding-style-props.html
+++ b/layout/doc/adding-style-props.html
@@ -282,17 +282,17 @@ Having implemented support for the new p
 Declaration classes in the content module, it is now time to provide support
 for the new property in layout. The Style Context must be given a new data
 member corresponding to the declaration's new data member, so the computed
 value can be held for the layout objects to use.<br>
   <br>
 First look into <a href="http://lxr.mozilla.org/seamonkey/source/content/shared/public/nsStyleStruct.h">
 nsStyleStruct.h</a>
  to see the existing style strucs. Find the one that you want to store the
-data on. In this example, we want to put it on the nsStyleUserInterface struct,
+data on. In this example, we want to put it on the nsStyleUI struct,
 however there is also a class nsStyleUIReset that holds the non-inherited
 values, so we will use that one (remember, our property is not inherited).
 Add a <a href="#ComputedStyleMember">data member</a>
  to hold the value:
   <pre>struct nsStyleUIReset {
   nsStyleUIReset(void);
   nsStyleUIReset(const nsStyleUIReset&amp; aOther);
   ~nsStyleUIReset(void);
--- a/layout/forms/nsImageControlFrame.cpp
+++ b/layout/forms/nsImageControlFrame.cpp
@@ -171,17 +171,17 @@ nsImageControlFrame::SetFocus(bool aOn, 
 }
 
 nsresult
 nsImageControlFrame::GetCursor(const nsPoint&    aPoint,
                                nsIFrame::Cursor& aCursor)
 {
   // Use style defined cursor if one is provided, otherwise when
   // the cursor style is "auto" we use the pointer cursor.
-  FillCursorInformationFromStyle(StyleUserInterface(), aCursor);
+  FillCursorInformationFromStyle(StyleUI(), aCursor);
 
   if (NS_STYLE_CURSOR_AUTO == aCursor.mCursor) {
     aCursor.mCursor = NS_STYLE_CURSOR_POINTER;
   }
 
   return NS_OK;
 }
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2388,17 +2388,17 @@ nsIFrame::DisplayCaret(nsDisplayListBuil
     return;
 
   aList->AppendToTop(MakeDisplayItem<nsDisplayCaret>(aBuilder, this));
 }
 
 nscolor
 nsIFrame::GetCaretColorAt(int32_t aOffset)
 {
-  return nsLayoutUtils::GetColor(this, &nsStyleUserInterface::mCaretColor);
+  return nsLayoutUtils::GetColor(this, &nsStyleUI::mCaretColor);
 }
 
 bool
 nsFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
                                         const nsDisplayListSet& aLists,
                                         bool aForceBackground)
 {
   // Here we don't try to detect background propagation. Frames that might
@@ -5197,17 +5197,17 @@ nsIFrame::AssociateImage(const nsStyleIm
   // If this fails there's not much we can do ...
   loader->AssociateRequestToFrame(req, this, aImageLoaderFlags);
 }
 
 nsresult
 nsFrame::GetCursor(const nsPoint& aPoint,
                    nsIFrame::Cursor& aCursor)
 {
-  FillCursorInformationFromStyle(StyleUserInterface(), aCursor);
+  FillCursorInformationFromStyle(StyleUI(), aCursor);
   if (NS_STYLE_CURSOR_AUTO == aCursor.mCursor) {
     // If this is editable, I-beam cursor is better for most elements.
     aCursor.mCursor =
       (mContent && mContent->IsEditable())
       ? NS_STYLE_CURSOR_TEXT : NS_STYLE_CURSOR_DEFAULT;
   }
   if (NS_STYLE_CURSOR_TEXT == aCursor.mCursor &&
       GetWritingMode().IsVertical()) {
@@ -6498,17 +6498,17 @@ nsFrame::Reflow(nsPresContext*          
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
 }
 
 bool
 nsIFrame::IsContentDisabled() const
 {
   // FIXME(emilio): Doing this via CSS means callers must ensure the style is up
   // to date, and they don't!
-  if (StyleUserInterface()->mUserInput == StyleUserInput::None) {
+  if (StyleUI()->mUserInput == StyleUserInput::None) {
     return true;
   }
 
   auto* element = nsGenericHTMLElement::FromNodeOrNull(GetContent());
   return element && element->IsDisabled();
 }
 
 nsresult
@@ -9992,17 +9992,17 @@ nsIFrame::IsFocusable(int32_t *aTabIndex
   if (aTabIndex) {
     *aTabIndex = -1; // Default for early return is not focusable
   }
   bool isFocusable = false;
 
   if (mContent && mContent->IsElement() && IsVisibleConsideringAncestors() &&
       Style()->GetPseudo() != nsCSSAnonBoxes::anonymousFlexItem &&
       Style()->GetPseudo() != nsCSSAnonBoxes::anonymousGridItem) {
-    const nsStyleUserInterface* ui = StyleUserInterface();
+    const nsStyleUI* ui = StyleUI();
     if (ui->mUserFocus != StyleUserFocus::Ignore &&
         ui->mUserFocus != StyleUserFocus::None) {
       // Pass in default tabindex of -1 for nonfocusable and 0 for focusable
       tabIndex = 0;
     }
     isFocusable = mContent->IsFocusable(&tabIndex, aWithMouse);
     if (!isFocusable && !aWithMouse && IsScrollFrame() &&
         mContent->IsHTMLElement() &&
@@ -10092,17 +10092,17 @@ nsIFrame::VerticalAlignEnum() const
   if (verticalAlign.GetUnit() == eStyleUnit_Enumerated) {
     return verticalAlign.GetIntValue();
   }
 
   return eInvalidVerticalAlign;
 }
 
 /* static */
-void nsFrame::FillCursorInformationFromStyle(const nsStyleUserInterface* ui,
+void nsFrame::FillCursorInformationFromStyle(const nsStyleUI* ui,
                                              nsIFrame::Cursor& aCursor)
 {
   aCursor.mCursor = ui->mCursor;
   aCursor.mHaveHotspot = false;
   aCursor.mLoading = false;
   aCursor.mHotspotX = aCursor.mHotspotY = 0.0f;
 
   for (const nsCursorImage& item : ui->mCursorImages) {
@@ -11257,17 +11257,17 @@ nsIFrame::GetCompositorHitTestInfo(nsDis
     return result;
   }
   if (!GetParent()) {
     MOZ_ASSERT(IsViewportFrame());
     // Viewport frames are never event targets, other frames, like canvas frames,
     // are the event targets for any regions viewport frames may cover.
     return result;
   }
-  const uint8_t pointerEvents = StyleUserInterface()->GetEffectivePointerEvents(this);
+  const uint8_t pointerEvents = StyleUI()->GetEffectivePointerEvents(this);
   if (pointerEvents == NS_STYLE_POINTER_EVENTS_NONE) {
     return result;
   }
   if (!StyleVisibility()->IsVisible()) {
     return result;
   }
 
   // Anything that didn't match the above conditions is visible to hit-testing.
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -680,17 +680,17 @@ protected:
   nsresult GetDataForTableSelection(const nsFrameSelection* aFrameSelection,
                                     nsIPresShell* aPresShell,
                                     mozilla::WidgetMouseEvent* aMouseEvent,
                                     nsIContent** aParentContent,
                                     int32_t* aContentOffset,
                                     mozilla::TableSelection* aTarget);
 
   // Fills aCursor with the appropriate information from ui
-  static void FillCursorInformationFromStyle(const nsStyleUserInterface* ui,
+  static void FillCursorInformationFromStyle(const nsStyleUI* ui,
                                              nsIFrame::Cursor& aCursor);
   NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override;
 
   nsBoxLayoutMetrics* BoxMetrics() const;
 
   // Fire DOM event. If no aContent argument use frame's mContent.
   void FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent = nullptr);
 
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -2196,18 +2196,17 @@ nsImageFrame::GetCursor(const nsPoint& a
       // XXX Using the image as the parent ComputedStyle isn't
       // technically correct, but it's probably the right thing to do
       // here, since it means that areas on which the cursor isn't
       // specified will inherit the style from the image.
       RefPtr<ComputedStyle> areaStyle =
         PresShell()->StyleSet()->
           ResolveStyleFor(area->AsElement(), Style(),
                           LazyComputeBehavior::Allow);
-      FillCursorInformationFromStyle(areaStyle->StyleUserInterface(),
-                                     aCursor);
+      FillCursorInformationFromStyle(areaStyle->StyleUI(), aCursor);
       if (NS_STYLE_CURSOR_AUTO == aCursor.mCursor) {
         aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT;
       }
       return NS_OK;
     }
   }
   return nsFrame::GetCursor(aPoint, aCursor);
 }
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -335,17 +335,17 @@ nsSubDocumentFrame::BuildDisplayList(nsD
   nsFrameLoader* frameLoader = FrameLoader();
   RenderFrameParent* rfp = nullptr;
   if (frameLoader) {
     rfp = frameLoader->GetCurrentRenderFrame();
   }
 
   // If we are pointer-events:none then we don't need to HitTest background
   bool pointerEventsNone =
-    StyleUserInterface()->mPointerEvents == NS_STYLE_POINTER_EVENTS_NONE;
+    StyleUI()->mPointerEvents == NS_STYLE_POINTER_EVENTS_NONE;
   if (!aBuilder->IsForEventDelivery() || !pointerEventsNone) {
     nsDisplayListCollection decorations(aBuilder);
     DisplayBorderBackgroundOutline(aBuilder, decorations);
     if (rfp) {
       // Wrap background colors of <iframe>s with remote subdocuments in their
       // own layer so we generate a ColorLayer. This is helpful for optimizing
       // compositing; we can skip compositing the ColorLayer when the
       // remote content is opaque.
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -4628,17 +4628,17 @@ NS_IMPL_FRAMEARENA_HELPERS(nsContinuingT
 nsTextFrame::~nsTextFrame()
 {
 }
 
 nsresult
 nsTextFrame::GetCursor(const nsPoint& aPoint,
                        nsIFrame::Cursor& aCursor)
 {
-  FillCursorInformationFromStyle(StyleUserInterface(), aCursor);
+  FillCursorInformationFromStyle(StyleUI(), aCursor);
   if (NS_STYLE_CURSOR_AUTO == aCursor.mCursor) {
     if (!IsSelectable(nullptr)) {
       aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT;
     } else {
       aCursor.mCursor = GetWritingMode().IsVertical()
         ? NS_STYLE_CURSOR_VERTICAL_TEXT : NS_STYLE_CURSOR_TEXT;
     }
     return NS_OK;
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -346,17 +346,17 @@ RenderFrameParent::EnsureLayersConnected
 nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
                                  nsSubDocumentFrame* aFrame,
                                  RenderFrameParent* aRemoteFrame)
   : nsDisplayItem(aBuilder, aFrame)
   , mRemoteFrame(aRemoteFrame)
   , mEventRegionsOverride(EventRegionsOverride::NoOverride)
 {
   bool frameIsPointerEventsNone =
-    aFrame->StyleUserInterface()->GetEffectivePointerEvents(aFrame) ==
+    aFrame->StyleUI()->GetEffectivePointerEvents(aFrame) ==
       NS_STYLE_POINTER_EVENTS_NONE;
   if (aBuilder->IsInsidePointerEventsNoneDoc() || frameIsPointerEventsNone) {
     mEventRegionsOverride |= EventRegionsOverride::ForceEmptyHitRegion;
   }
   if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(aFrame->PresShell())) {
     mEventRegionsOverride |= EventRegionsOverride::ForceDispatchToContent;
   }
 }
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2846,17 +2846,17 @@ GetMouseThrough(const nsIFrame* aFrame)
   }
   return false;
 }
 
 static bool
 IsFrameReceivingPointerEvents(nsIFrame* aFrame)
 {
   return NS_STYLE_POINTER_EVENTS_NONE !=
-    aFrame->StyleUserInterface()->GetEffectivePointerEvents(aFrame);
+    aFrame->StyleUI()->GetEffectivePointerEvents(aFrame);
 }
 
 // A list of frames, and their z depth. Used for sorting
 // the results of hit testing.
 struct FramesWithDepth
 {
   explicit FramesWithDepth(float aDepth) :
     mDepth(aDepth)
--- a/layout/style/ComputedStyle.cpp
+++ b/layout/style/ComputedStyle.cpp
@@ -126,17 +126,17 @@ ComputedStyle::CalcStyleDifference(Compu
 
   // FIXME: The order of these DO_STRUCT_DIFFERENCE calls is no longer
   // significant.  With a small amount of effort, we could replace them with a
   // #include "nsStyleStructList.h".
   DO_STRUCT_DIFFERENCE(Display);
   DO_STRUCT_DIFFERENCE(XUL);
   DO_STRUCT_DIFFERENCE(Column);
   DO_STRUCT_DIFFERENCE(Content);
-  DO_STRUCT_DIFFERENCE(UserInterface);
+  DO_STRUCT_DIFFERENCE(UI);
   DO_STRUCT_DIFFERENCE(Visibility);
   DO_STRUCT_DIFFERENCE(Outline);
   DO_STRUCT_DIFFERENCE(TableBorder);
   DO_STRUCT_DIFFERENCE(Table);
   DO_STRUCT_DIFFERENCE(UIReset);
   DO_STRUCT_DIFFERENCE(Text);
   DO_STRUCT_DIFFERENCE_WITH_ARGS(List, (, PEEK(Display)));
   DO_STRUCT_DIFFERENCE(SVGReset);
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -1571,35 +1571,34 @@ Gecko_CopyImageValueFrom(nsStyleImage* a
 void
 Gecko_InitializeImageCropRect(nsStyleImage* aImage)
 {
   MOZ_ASSERT(aImage);
   aImage->SetCropRect(MakeUnique<nsStyleSides>());
 }
 
 void
-Gecko_SetCursorArrayLength(nsStyleUserInterface* aStyleUI, size_t aLen)
+Gecko_SetCursorArrayLength(nsStyleUI* aStyleUI, size_t aLen)
 {
   aStyleUI->mCursorImages.Clear();
   aStyleUI->mCursorImages.SetLength(aLen);
 }
 
 void
 Gecko_SetCursorImageValue(nsCursorImage* aCursor,
                           mozilla::css::ImageValue* aImageValue)
 {
   MOZ_ASSERT(aCursor && aImageValue);
 
   aCursor->mImage =
     CreateStyleImageRequest(nsStyleImageRequest::Mode::Discard, aImageValue);
 }
 
 void
-Gecko_CopyCursorArrayFrom(nsStyleUserInterface* aDest,
-                          const nsStyleUserInterface* aSrc)
+Gecko_CopyCursorArrayFrom(nsStyleUI* aDest, const nsStyleUI* aSrc)
 {
   aDest->mCursorImages = aSrc->mCursorImages;
 }
 
 void
 Gecko_SetContentDataImageValue(nsStyleContentData* aContent,
                                mozilla::css::ImageValue* aImageValue)
 {
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -374,21 +374,20 @@ const nsStyleGradient* Gecko_GetGradient
 
 // list-style-image style.
 void Gecko_SetListStyleImageNone(nsStyleList* style_struct);
 void Gecko_SetListStyleImageImageValue(nsStyleList* style_struct,
                                   mozilla::css::ImageValue* aImageValue);
 void Gecko_CopyListStyleImageFrom(nsStyleList* dest, const nsStyleList* src);
 
 // cursor style.
-void Gecko_SetCursorArrayLength(nsStyleUserInterface* ui, size_t len);
+void Gecko_SetCursorArrayLength(nsStyleUI* ui, size_t len);
 void Gecko_SetCursorImageValue(nsCursorImage* aCursor,
                                mozilla::css::ImageValue* aImageValue);
-void Gecko_CopyCursorArrayFrom(nsStyleUserInterface* dest,
-                               const nsStyleUserInterface* src);
+void Gecko_CopyCursorArrayFrom(nsStyleUI* dest, const nsStyleUI* src);
 
 void Gecko_SetContentDataImageValue(nsStyleContentData* aList,
                                     mozilla::css::ImageValue* aImageValue);
 nsStyleContentData::CounterFunction* Gecko_SetCounterFunction(
     nsStyleContentData* content_data, mozilla::StyleContentType);
 
 // Dirtiness tracking.
 void Gecko_SetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags);
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -333,17 +333,17 @@ whitelist-types = [
     "nsStyleSVGReset",
     "nsStyleTable",
     "nsStyleTableBorder",
     "nsStyleText",
     "nsStyleTextReset",
     "nsStyleUIReset",
     "nsStyleUnion",
     "nsStyleUnit",
-    "nsStyleUserInterface",
+    "nsStyleUI",
     "nsStyleVisibility",
     "nsStyleXUL",
     "nsTArrayHeader",
     "Position",
     "PropertyValuePair",
     "Runnable",
     "ServoAttrSnapshot",
     "ServoBundledURI",
@@ -580,17 +580,17 @@ structs-types = [
     "nsStyleSides",
     "nsStyleTable",
     "nsStyleTableBorder",
     "nsStyleText",
     "nsStyleTextReset",
     "nsStyleUIReset",
     "nsStyleUnion",
     "nsStyleUnit",
-    "nsStyleUserInterface",
+    "nsStyleUI",
     "nsStyleVisibility",
     "nsStyleXUL",
     "nsTimingFunction",
     "nscolor",
     "nscoord",
     "nsresult",
     "Loader",
     "LoaderReusableStyleSheets",
--- a/layout/style/nsCSSVisitedDependentPropList.h
+++ b/layout/style/nsCSSVisitedDependentPropList.h
@@ -28,9 +28,9 @@ STYLE_STRUCT(Border, (mBorderTopColor,
                       mBorderLeftColor))
 STYLE_STRUCT(Outline, (mOutlineColor))
 STYLE_STRUCT(Column, (mColumnRuleColor))
 STYLE_STRUCT(Text, (mTextEmphasisColor,
                     mWebkitTextFillColor,
                     mWebkitTextStrokeColor))
 STYLE_STRUCT(TextReset, (mTextDecorationColor))
 STYLE_STRUCT(SVG, (mFill, mStroke))
-STYLE_STRUCT(UserInterface, (mCaretColor))
+STYLE_STRUCT(UI, (mCaretColor))
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -722,17 +722,17 @@ CollectImageURLsForProperty(nsCSSPropert
     CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProp, CSSEnabledState::eForAllContent) {
       CollectImageURLsForProperty(*p, aStyle, aURLs);
     }
     return;
   }
 
   switch (aProp) {
     case eCSSProperty_cursor:
-      for (auto& image : aStyle.StyleUserInterface()->mCursorImages) {
+      for (auto& image : aStyle.StyleUI()->mCursorImages) {
         AddImageURL(*image.mImage, aURLs);
       }
       break;
     case eCSSProperty_background_image:
       AddImageURLs(aStyle.StyleBackground()->mImage, aURLs);
       break;
     case eCSSProperty_mask_clip:
       AddImageURLs(aStyle.StyleSVGReset()->mMask, aURLs);
@@ -2980,26 +2980,26 @@ nsComputedDOMStyle::DoGetScrollSnapCoord
     return valueList.forget();
   }
 }
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetScrollbarFaceColor()
 {
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
-  SetValueForWidgetColor(val, StyleUserInterface()->mScrollbarFaceColor,
+  SetValueForWidgetColor(val, StyleUI()->mScrollbarFaceColor,
                          StyleAppearance::ScrollbarthumbVertical);
   return val.forget();
 }
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetScrollbarTrackColor()
 {
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
-  SetValueForWidgetColor(val, StyleUserInterface()->mScrollbarTrackColor,
+  SetValueForWidgetColor(val, StyleUI()->mScrollbarTrackColor,
                          StyleAppearance::ScrollbarVertical);
   return val.forget();
 }
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetOutlineWidth()
 {
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
@@ -3472,26 +3472,26 @@ nsComputedDOMStyle::DoGetWebkitTextStrok
 
 static_assert(NS_STYLE_UNICODE_BIDI_NORMAL == 0,
               "unicode-bidi style constants not as expected");
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetCaretColor()
 {
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
-  SetValueFromComplexColor(val, StyleUserInterface()->mCaretColor);
+  SetValueFromComplexColor(val, StyleUI()->mCaretColor);
   return val.forget();
 }
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetCursor()
 {
   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
 
-  const nsStyleUserInterface *ui = StyleUserInterface();
+  const nsStyleUI *ui = StyleUI();
 
   for (const nsCursorImage& item : ui->mCursorImages) {
     RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false);
 
     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
     SetValueToURLValue(item.mImage->GetImageValue(), val);
     itemList->AppendCSSValue(val.forget());
 
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -377,17 +377,17 @@ enum class StyleBorderImageRepeat : uint
 enum class StyleContent : uint8_t {
   OpenQuote,
   CloseQuote,
   NoOpenQuote,
   NoCloseQuote,
   AltContent
 };
 
-// See nsStyleUserInterface
+// See nsStyleUI
 #define NS_STYLE_CURSOR_AUTO                    1
 #define NS_STYLE_CURSOR_CROSSHAIR               2
 #define NS_STYLE_CURSOR_DEFAULT                 3    // ie: an arrow
 #define NS_STYLE_CURSOR_POINTER                 4    // for links
 #define NS_STYLE_CURSOR_MOVE                    5
 #define NS_STYLE_CURSOR_E_RESIZE                6
 #define NS_STYLE_CURSOR_NE_RESIZE               7
 #define NS_STYLE_CURSOR_NW_RESIZE               8
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -4554,17 +4554,17 @@ nsStyleText::TextEmphasisSide(WritingMod
     (mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_OVER
      ? eSideTop : eSideBottom);
   LogicalSide result = aWM.LogicalSideForPhysicalSide(side);
   MOZ_ASSERT(IsBlock(result));
   return result;
 }
 
 //-----------------------
-// nsStyleUserInterface
+// nsStyleUI
 //
 
 nsCursorImage::nsCursorImage()
   : mHaveHotspot(false)
   , mHotspotX(0.0f)
   , mHotspotY(0.0f)
 {
 }
@@ -4600,51 +4600,51 @@ nsCursorImage::operator==(const nsCursor
                (aOther.mHotspotX == 0 && aOther.mHotspotY == 0),
                "expected mHotspot{X,Y} to be 0 when mHaveHotspot is false");
   return mHaveHotspot == aOther.mHaveHotspot &&
          mHotspotX == aOther.mHotspotX &&
          mHotspotY == aOther.mHotspotY &&
          DefinitelyEqualImages(mImage, aOther.mImage);
 }
 
-nsStyleUserInterface::nsStyleUserInterface(const nsPresContext* aContext)
+nsStyleUI::nsStyleUI(const nsPresContext* aContext)
   : mUserInput(StyleUserInput::Auto)
   , mUserModify(StyleUserModify::ReadOnly)
   , mUserFocus(StyleUserFocus::None)
   , mPointerEvents(NS_STYLE_POINTER_EVENTS_AUTO)
   , mCursor(NS_STYLE_CURSOR_AUTO)
   , mCaretColor(StyleComplexColor::Auto())
   , mScrollbarFaceColor(StyleComplexColor::Auto())
   , mScrollbarTrackColor(StyleComplexColor::Auto())
 {
-  MOZ_COUNT_CTOR(nsStyleUserInterface);
-}
-
-nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface& aSource)
+  MOZ_COUNT_CTOR(nsStyleUI);
+}
+
+nsStyleUI::nsStyleUI(const nsStyleUI& aSource)
   : mUserInput(aSource.mUserInput)
   , mUserModify(aSource.mUserModify)
   , mUserFocus(aSource.mUserFocus)
   , mPointerEvents(aSource.mPointerEvents)
   , mCursor(aSource.mCursor)
   , mCursorImages(aSource.mCursorImages)
   , mCaretColor(aSource.mCaretColor)
   , mScrollbarFaceColor(aSource.mScrollbarFaceColor)
   , mScrollbarTrackColor(aSource.mScrollbarTrackColor)
 {
-  MOZ_COUNT_CTOR(nsStyleUserInterface);
-}
-
-nsStyleUserInterface::~nsStyleUserInterface()
-{
-  MOZ_COUNT_DTOR(nsStyleUserInterface);
+  MOZ_COUNT_CTOR(nsStyleUI);
+}
+
+nsStyleUI::~nsStyleUI()
+{
+  MOZ_COUNT_DTOR(nsStyleUI);
 }
 
 void
-nsStyleUserInterface::FinishStyle(
-  nsPresContext* aPresContext, const nsStyleUserInterface* aOldStyle)
+nsStyleUI::FinishStyle(nsPresContext* aPresContext,
+                       const nsStyleUI* aOldStyle)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   for (size_t i = 0; i < mCursorImages.Length(); ++i) {
     nsCursorImage& cursor = mCursorImages[i];
 
     if (cursor.mImage && !cursor.mImage->IsResolved()) {
       const nsCursorImage* oldCursor =
@@ -4653,17 +4653,17 @@ nsStyleUserInterface::FinishStyle(
         : nullptr;
       cursor.mImage->Resolve(
         aPresContext, oldCursor ? oldCursor->mImage.get() : nullptr);
     }
   }
 }
 
 nsChangeHint
-nsStyleUserInterface::CalcDifference(const nsStyleUserInterface& aNewData) const
+nsStyleUI::CalcDifference(const nsStyleUI& aNewData) const
 {
   nsChangeHint hint = nsChangeHint(0);
   if (mCursor != aNewData.mCursor) {
     hint |= nsChangeHint_UpdateCursor;
   }
 
   // We could do better. But it wouldn't be worth it, URL-specified cursors are
   // rare.
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2771,26 +2771,26 @@ struct nsCursorImage
     return !(*this == aOther);
   }
 
   imgRequestProxy* GetImage() const {
     return mImage->get();
   }
 };
 
-struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUserInterface
+struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUI
 {
-  explicit nsStyleUserInterface(const nsPresContext* aContext);
-  nsStyleUserInterface(const nsStyleUserInterface& aOther);
-  ~nsStyleUserInterface();
-
-  void FinishStyle(nsPresContext*, const nsStyleUserInterface*);
+  explicit nsStyleUI(const nsPresContext* aContext);
+  nsStyleUI(const nsStyleUI& aOther);
+  ~nsStyleUI();
+
+  void FinishStyle(nsPresContext*, const nsStyleUI*);
   const static bool kHasFinishStyle = true;
 
-  nsChangeHint CalcDifference(const nsStyleUserInterface& aNewData) const;
+  nsChangeHint CalcDifference(const nsStyleUI& aNewData) const;
 
   mozilla::StyleUserInput   mUserInput;
   mozilla::StyleUserModify  mUserModify;      // (modify-content)
   mozilla::StyleUserFocus   mUserFocus;       // (auto-select)
   uint8_t                   mPointerEvents;   // NS_STYLE_POINTER_EVENTS_*
 
   uint8_t mCursor;                            // NS_STYLE_CURSOR_*
   nsTArray<nsCursorImage> mCursorImages;      // images and coords
--- a/layout/style/nsStyleStructInlines.h
+++ b/layout/style/nsStyleStructInlines.h
@@ -241,26 +241,26 @@ bool
 nsStyleDisplay::IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const
 {
   NS_ASSERTION(aContextFrame->StyleDisplay() == this, "unexpected aContextFrame");
   return IsAbsolutelyPositionedStyle() &&
          !nsSVGUtils::IsInSVGTextSubtree(aContextFrame);
 }
 
 uint8_t
-nsStyleUserInterface::GetEffectivePointerEvents(nsIFrame* aFrame) const
+nsStyleUI::GetEffectivePointerEvents(nsIFrame* aFrame) const
 {
   if (aFrame->GetContent() && !aFrame->GetContent()->GetParent()) {
     // The root element has a cluster of frames associated with it
     // (root scroll frame, canvas frame, the actual primary frame). Make
     // those take their pointer-events value from the root element's primary
     // frame.
     nsIFrame* f = aFrame->GetContent()->GetPrimaryFrame();
     if (f) {
-      return f->StyleUserInterface()->mPointerEvents;
+      return f->StyleUI()->mPointerEvents;
     }
   }
   return mPointerEvents;
 }
 
 bool
 nsStyleBackground::HasLocalBackground() const
 {
--- a/layout/style/nsStyleStructList.h
+++ b/layout/style/nsStyleStructList.h
@@ -32,17 +32,17 @@
 // nsStyleStructFwd.h that want the structs in id-order just define
 // STYLE_STRUCT rather than including the file twice.
 
 STYLE_STRUCT_INHERITED(Font)
 STYLE_STRUCT_INHERITED(Color)
 STYLE_STRUCT_INHERITED(List)
 STYLE_STRUCT_INHERITED(Text)
 STYLE_STRUCT_INHERITED(Visibility)
-STYLE_STRUCT_INHERITED(UserInterface)
+STYLE_STRUCT_INHERITED(UI)
 STYLE_STRUCT_INHERITED(TableBorder)
 STYLE_STRUCT_INHERITED(SVG)
 
 STYLE_STRUCT_RESET(Background)
 STYLE_STRUCT_RESET(Position)
 STYLE_STRUCT_RESET(TextReset)
 STYLE_STRUCT_RESET(Display)
 STYLE_STRUCT_RESET(Content)
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -497,17 +497,17 @@ nsSVGImageFrame::ReflowCallbackCanceled(
   mReflowCallbackPosted = false;
 }
 
 uint16_t
 nsSVGImageFrame::GetHitTestFlags()
 {
   uint16_t flags = 0;
 
-  switch (StyleUserInterface()->mPointerEvents) {
+  switch (StyleUI()->mPointerEvents) {
     case NS_STYLE_POINTER_EVENTS_NONE:
       break;
     case NS_STYLE_POINTER_EVENTS_VISIBLEPAINTED:
     case NS_STYLE_POINTER_EVENTS_AUTO:
       if (StyleVisibility()->IsVisible()) {
         /* XXX: should check pixel transparency */
         flags |= SVG_HIT_TEST_FILL;
       }
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1699,17 +1699,17 @@ nsSVGUtils::SetupStrokeGeometry(nsIFrame
                     strokeOptions.mDashOffset);
 }
 
 uint16_t
 nsSVGUtils::GetGeometryHitTestFlags(nsIFrame* aFrame)
 {
   uint16_t flags = 0;
 
-  switch (aFrame->StyleUserInterface()->mPointerEvents) {
+  switch (aFrame->StyleUI()->mPointerEvents) {
   case NS_STYLE_POINTER_EVENTS_NONE:
     break;
   case NS_STYLE_POINTER_EVENTS_AUTO:
   case NS_STYLE_POINTER_EVENTS_VISIBLEPAINTED:
     if (aFrame->StyleVisibility()->IsVisible()) {
       if (aFrame->StyleSVG()->mFill.Type() != eStyleSVGPaintType_None)
         flags |= SVG_HIT_TEST_FILL;
       if (aFrame->StyleSVG()->mStroke.Type() != eStyleSVGPaintType_None)
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -2437,18 +2437,17 @@ nsTreeBodyFrame::GetCursor(const nsPoint
     nsTreeColumn* col;
     nsICSSAnonBoxPseudo* child;
     GetCellAt(aPoint.x, aPoint.y, &row, &col, &child);
 
     if (child) {
       // Our scratch array is already prefilled.
       ComputedStyle* childContext = GetPseudoComputedStyle(child);
 
-      FillCursorInformationFromStyle(childContext->StyleUserInterface(),
-                                     aCursor);
+      FillCursorInformationFromStyle(childContext->StyleUI(), aCursor);
       if (aCursor.mCursor == NS_STYLE_CURSOR_AUTO)
         aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT;
 
       return NS_OK;
     }
   }
 
   return nsLeafBoxFrame::GetCursor(aPoint, aCursor);
--- a/media/webrtc/signaling/gtest/sdp_unittests.cpp
+++ b/media/webrtc/signaling/gtest/sdp_unittests.cpp
@@ -4142,16 +4142,83 @@ TEST(NewSdpTestNoFixture, CheckParsingRe
     auto rustSdp = rustParser.Parse(sdp_string);
 
     ParsingResultComparer comparer;
     return comparer.Compare(*rustSdp, *sipccSdp, sdp_string);
   };
 
   ASSERT_TRUE(check_comparison(kBasicAudioVideoOffer));
   ASSERT_TRUE(check_comparison(kH264AudioVideoOffer));
+
+  // Check the Fmtp comprison
+  const std::string kBasicOpusFmtp1 =
+  "v=0" CRLF
+  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
+  "s=SIP Call" CRLF
+  "c=IN IP4 224.0.0.1/100/12" CRLF
+  "t=0 0" CRLF
+  "m=video 9 RTP/SAVPF 120" CRLF
+  "a=rtpmap:120 opus/48000" CRLF
+  "a=fmtp:120 stereo=1;useinbandfec=1" CRLF;
+  ASSERT_TRUE(check_comparison(kBasicOpusFmtp1));
+
+  const std::string kBasicOpusFmtp2 =
+  "v=0" CRLF
+  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
+  "s=SIP Call" CRLF
+  "c=IN IP4 224.0.0.1/100/12" CRLF
+  "t=0 0" CRLF
+  "m=video 9 RTP/SAVPF 120" CRLF
+  "a=rtpmap:120 opus/48000" CRLF
+  "a=fmtp:120 useinbandfec=1;stereo=1;maxplaybackrate=32000" CRLF;
+  ASSERT_TRUE(check_comparison(kBasicOpusFmtp2));
+
+  const std::string kBasicVP8Fmtp1 =
+  "v=0" CRLF
+  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
+  "s=SIP Call" CRLF
+  "c=IN IP4 224.0.0.1/100/12" CRLF
+  "t=0 0" CRLF
+  "m=video 9 RTP/SAVPF 120" CRLF
+  "a=rtpmap:120 VP8/90000" CRLF
+  "a=fmtp:120 max-fs=3600;max-fr=60" CRLF;
+  ASSERT_TRUE(check_comparison(kBasicVP8Fmtp1));
+  //
+  const std::string kBasicVP8Fmtp2 =
+  "v=0" CRLF
+  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
+  "s=SIP Call" CRLF
+  "c=IN IP4 224.0.0.1/100/12" CRLF
+  "t=0 0" CRLF
+  "m=video 9 RTP/SAVPF 120" CRLF
+  "a=rtpmap:120 VP8/90000" CRLF
+  "a=fmtp:120 max-fr=60;max-fs=3600" CRLF;
+  ASSERT_TRUE(check_comparison(kBasicVP8Fmtp2));
+
+  const std::string kBasicH264Fmtp1 =
+  "v=0" CRLF
+  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
+  "s=SIP Call" CRLF
+  "c=IN IP4 224.0.0.1/100/12" CRLF
+  "t=0 0" CRLF
+  "m=video 9 RTP/SAVPF 120" CRLF
+  "a=rtpmap:120 H264/90000" CRLF
+  "a=fmtp:120 profile-level-id=42a01e;level_asymmetry_allowed=1" CRLF;
+  ASSERT_TRUE(check_comparison(kBasicH264Fmtp1));
+
+  const std::string kBasicH264Fmtp2 =
+  "v=0" CRLF
+  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
+  "s=SIP Call" CRLF
+  "c=IN IP4 224.0.0.1/100/12" CRLF
+  "t=0 0" CRLF
+  "m=video 9 RTP/SAVPF 120" CRLF
+  "a=rtpmap:120 H264/90000" CRLF
+  "a=fmtp:120 level_asymmetry_allowed=1;profile-level-id=42a01e;max_fs=3600" CRLF;
+  ASSERT_TRUE(check_comparison(kBasicH264Fmtp2));
 }
 
 TEST(NewSdpTestNoFixture, CheckAttributeTypeSerialize) {
   for (auto a = static_cast<size_t>(SdpAttribute::kFirstAttribute);
        a <= static_cast<size_t>(SdpAttribute::kLastAttribute);
        ++a) {
 
     SdpAttribute::AttributeType type =
--- a/media/webrtc/signaling/src/sdp/ParsingResultComparer.cpp
+++ b/media/webrtc/signaling/src/sdp/ParsingResultComparer.cpp
@@ -207,16 +207,23 @@ ParsingResultComparer::CompareAttrLists(
 
         result = false;
         continue;
       }
 
       auto rustAttrStr = ToString(*rustAttrlist.GetAttribute(type, false));
 
       if (rustAttrStr != sipccAttrStr) {
+
+        if (type == AttributeType::kFmtpAttribute) {
+          if (rustAttrlist.GetFmtp() == sipccAttrlist.GetFmtp()) {
+            continue;
+          }
+        }
+
         std::string originalAttrStr = GetAttributeLines(attrStr, level);
         if (rustAttrStr != originalAttrStr) {
           nsString typeStr;
           typeStr.AssignASCII(attrStr.c_str());
           typeStr += NS_LITERAL_STRING("_inequal");
           Telemetry::ScalarAdd(Telemetry::ScalarID::WEBRTC_SDP_PARSER_DIFF,
                                typeStr, 1);
           LOGD(("%s is neither equal to sipcc nor to the orginal sdp\n"
--- a/media/webrtc/signaling/src/sdp/SdpAttribute.cpp
+++ b/media/webrtc/signaling/src/sdp/SdpAttribute.cpp
@@ -172,16 +172,22 @@ SdpFingerprintAttributeList::ParseFinger
       fp.clear(); // error
       return fp;
     }
     fp[fpIndex++] = high << 4 | low;
   }
   return fp;
 }
 
+bool
+SdpFmtpAttributeList::operator==(const SdpFmtpAttributeList& other) const
+{
+  return mFmtps == other.mFmtps;
+}
+
 void
 SdpFmtpAttributeList::Serialize(std::ostream& os) const
 {
   for (auto i = mFmtps.begin(); i != mFmtps.end(); ++i) {
     if (i->parameters) {
       os << "a=" << mType << ":" << i->format << " ";
       i->parameters->Serialize(os);
       os << CRLF;
--- a/media/webrtc/signaling/src/sdp/SdpAttribute.h
+++ b/media/webrtc/signaling/src/sdp/SdpAttribute.h
@@ -1278,16 +1278,23 @@ public:
     explicit Parameters(SdpRtpmapAttributeList::CodecType aCodec)
         : codec_type(aCodec)
     {
     }
 
     virtual ~Parameters() {}
     virtual Parameters* Clone() const = 0;
     virtual void Serialize(std::ostream& os) const = 0;
+    virtual bool CompareEq(const Parameters& other) const = 0;
+
+    bool operator==(const Parameters& other) const
+    {
+        return codec_type == other.codec_type &&
+               CompareEq(other);
+    }
 
     SdpRtpmapAttributeList::CodecType codec_type;
   };
 
   class RedParameters : public Parameters
   {
   public:
     RedParameters()
@@ -1305,16 +1312,22 @@ public:
     Serialize(std::ostream& os) const override
     {
       for(size_t i = 0; i < encodings.size(); ++i) {
         os << (i != 0 ? "/" : "")
            << std::to_string(encodings[i]);
       }
     }
 
+    virtual bool
+    CompareEq(const Parameters& other) const override
+    {
+      return encodings == static_cast<const RedParameters&>(other).encodings;
+    }
+
     std::vector<uint8_t> encodings;
   };
 
   class H264Parameters : public Parameters
   {
   public:
     static const uint32_t kDefaultProfileLevelId = 0x420010;
 
@@ -1372,16 +1385,32 @@ public:
         os << ";max-dpb=" << max_dpb;
       }
 
       if (max_br != 0) {
         os << ";max-br=" << max_br;
       }
     }
 
+    virtual bool
+    CompareEq(const Parameters& other) const override
+    {
+      const auto& otherH264 = static_cast<const H264Parameters&>(other);
+
+      // sprop is not comapred here as it does not get parsed in the rsdparsa
+      return packetization_mode == otherH264.packetization_mode &&
+             level_asymmetry_allowed == otherH264.level_asymmetry_allowed &&
+             profile_level_id == otherH264.profile_level_id &&
+             max_mbps == otherH264.max_mbps &&
+             max_fs == otherH264.max_fs &&
+             max_cpb == otherH264.max_cpb &&
+             max_dpb == otherH264.max_dpb &&
+             max_br == otherH264.max_br;
+    }
+
     static const size_t max_sprop_len = 128;
     char sprop_parameter_sets[max_sprop_len];
     unsigned int packetization_mode;
     bool level_asymmetry_allowed;
     unsigned int profile_level_id;
     unsigned int max_mbps;
     unsigned int max_fs;
     unsigned int max_cpb;
@@ -1408,16 +1437,25 @@ public:
     Serialize(std::ostream& os) const override
     {
       // draft-ietf-payload-vp8-11 says these are mandatory, upper layer
       // needs to ensure they're set properly.
       os << "max-fs=" << max_fs;
       os << ";max-fr=" << max_fr;
     }
 
+    virtual bool
+    CompareEq(const Parameters& other) const override
+    {
+      const auto& otherVP8 = static_cast<const VP8Parameters&>(other);
+
+      return max_fs == otherVP8.max_fs &&
+             max_fr == otherVP8.max_fr;
+    }
+
     unsigned int max_fs;
     unsigned int max_fr;
   };
 
   class OpusParameters : public Parameters
   {
   public:
     enum { kDefaultMaxPlaybackRate = 48000,
@@ -1439,16 +1477,35 @@ public:
     void
     Serialize(std::ostream& os) const override
     {
       os << "maxplaybackrate=" << maxplaybackrate
          << ";stereo=" << stereo
          << ";useinbandfec=" << useInBandFec;
     }
 
+    virtual bool
+    CompareEq(const Parameters& other) const override
+    {
+      const auto& otherOpus = static_cast<const OpusParameters&>(other);
+
+      bool maxplaybackrateIsEq = (maxplaybackrate == otherOpus.maxplaybackrate);
+
+      // This is due to a bug in sipcc that causes maxplaybackrate to
+      // always be 0 if it appears in the fmtp
+      if (((maxplaybackrate == 0) && (otherOpus.maxplaybackrate != 0)) ||
+          ((maxplaybackrate != 0) && (otherOpus.maxplaybackrate == 0))) {
+           maxplaybackrateIsEq = true;
+       }
+
+      return maxplaybackrateIsEq &&
+             stereo == otherOpus.stereo &&
+             useInBandFec == otherOpus.useInBandFec;
+    }
+
     unsigned int maxplaybackrate;
     unsigned int stereo;
     unsigned int useInBandFec;
   };
 
   class TelephoneEventParameters : public Parameters
   {
   public:
@@ -1464,16 +1521,23 @@ public:
     }
 
     void
     Serialize(std::ostream& os) const override
     {
       os << dtmfTones;
     }
 
+    virtual bool
+    CompareEq(const Parameters& other) const override
+    {
+      return dtmfTones == static_cast<const TelephoneEventParameters&>(other)
+                          .dtmfTones;
+    }
+
     std::string dtmfTones;
   };
 
   class Fmtp
   {
   public:
     Fmtp(const std::string& aFormat, UniquePtr<Parameters> aParameters)
         : format(aFormat),
@@ -1494,27 +1558,35 @@ public:
     {
       if (this != &rhs) {
         format = rhs.format;
         parameters.reset(rhs.parameters ? rhs.parameters->Clone() : nullptr);
       }
       return *this;
     }
 
+    bool operator==(const Fmtp& other) const
+    {
+      return format == other.format &&
+             *parameters == *other.parameters;
+    }
+
     // The contract around these is as follows:
     // * |parameters| is only set if we recognized the media type and had
     //   a subclass of Parameters to represent that type of parameters
     // * |parameters| is a best-effort representation; it might be missing
     //   stuff
     // * Parameters::codec_type tells you the concrete class, eg
     //   kH264 -> H264Parameters
     std::string format;
     UniquePtr<Parameters> parameters;
   };
 
+  bool operator==(const SdpFmtpAttributeList& other) const;
+
   virtual void Serialize(std::ostream& os) const override;
 
   void
   PushEntry(const std::string& format, UniquePtr<Parameters> parameters)
   {
     mFmtps.push_back(Fmtp(format, std::move(parameters)));
   }
 
--- a/servo/components/style/properties/longhands/inherited_ui.mako.rs
+++ b/servo/components/style/properties/longhands/inherited_ui.mako.rs
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("InheritedUI", inherited=True, gecko_name="UserInterface") %>
+<% data.new_style_struct("InheritedUI", inherited=True, gecko_name="UI") %>
 
 ${helpers.predefined_type("cursor",
                           "Cursor",
                           "computed::Cursor::auto()",
                           initial_specified_value="specified::Cursor::auto()",
                           animation_value_type="discrete",
                           spec="https://drafts.csswg.org/css-ui/#cursor")}
 
--- a/testing/web-platform/meta/css/css-transitions/properties-value-002.html.ini
+++ b/testing/web-platform/meta/css/css-transitions/properties-value-002.html.ini
@@ -1,7 +1,9 @@
 [properties-value-002.html]
+  disabled:
+    if debug or asan: https://bugzilla.mozilla.org/show_bug.cgi?id=1358510
   [vertical-align vertical(keyword) / values]
     expected: FAIL
 
   [vertical-align vertical(keyword) / events]
     expected: FAIL
 
--- a/testing/web-platform/meta/css/css-transitions/properties-value-003.html.ini
+++ b/testing/web-platform/meta/css/css-transitions/properties-value-003.html.ini
@@ -1,9 +1,11 @@
 [properties-value-003.html]
+  disabled:
+    if debug or asan: https://bugzilla.mozilla.org/show_bug.cgi?id=1358510
   [background-image image(url) / values]
     expected: FAIL
 
   [background-image image(url) / events]
     expected: FAIL
 
   [background-image image(data) / values]
     expected: FAIL
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -628,25 +628,25 @@ devtools.main:
     notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
     record_in_processes: ["main"]
     description: User has clicked a link to a source file in the web console.
     release_channel_collection: opt-out
     expiry_version: never
     extra_keys:
       session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.
   filters_changed:
-    objects: ["webconsole"]
-    bug_numbers: [1463095]
+    objects: ["netmonitor", "webconsole"]
+    bug_numbers: [1463144, 1463095]
     notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
     record_in_processes: ["main"]
     description: User has changed filters in the web console.
     release_channel_collection: opt-out
     expiry_version: never
     extra_keys:
-      trigger: "The cause of the filter change: error, warn, log, info, debug, css, netxhr, net, text or reset"
+      trigger: "The cause of the filter change: error, warn, log, info, debug, css, netxhr, net, text or reset and all, html, css, js, xhr, fonts, images, media, ws or other for netmonitor"
       active: Comma separated list of active filters.
       inactive: Comma separated list of inactive filters.
       session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.
   jump_to_definition:
     objects: ["webconsole"]
     bug_numbers: [1463101]
     notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
     record_in_processes: ["main"]
--- a/toolkit/components/telemetry/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/TelemetrySession.jsm
@@ -804,17 +804,17 @@ var Impl = {
       ret[ioCounter] = this._startupIO[ioCounter];
 
     let activeTicks = this._sessionActiveTicks;
     if (isSubsession) {
       activeTicks = this._sessionActiveTicks - this._subsessionStartActiveTicks;
     }
 
     if (clearSubsession) {
-      this._subsessionStartActiveTicks = activeTicks;
+      this._subsessionStartActiveTicks = this._sessionActiveTicks;
     }
 
     ret.activeTicks = activeTicks;
 
     return ret;
   },
 
   /**
--- a/toolkit/components/telemetry/tests/unit/test_TelemetrySession_activeTicks.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySession_activeTicks.js
@@ -1,15 +1,36 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/
 */
 
 ChromeUtils.import("resource://gre/modules/TelemetryController.jsm", this);
 ChromeUtils.import("resource://gre/modules/TelemetrySession.jsm", this);
 
+function tick(aHowMany) {
+  for (let i = 0; i < aHowMany; i++) {
+    Services.obs.notifyObservers(null, "user-interaction-active");
+  }
+}
+
+function checkSessionTicks(aExpected) {
+  let payload = TelemetrySession.getPayload();
+  Assert.equal(payload.simpleMeasurements.activeTicks, aExpected,
+               "Should record the expected number of active ticks for the session.");
+}
+
+function checkSubsessionTicks(aExpected, aClearSubsession) {
+  let payload = TelemetrySession.getPayload("main", aClearSubsession);
+  Assert.equal(payload.simpleMeasurements.activeTicks, aExpected,
+               "Should record the expected number of active ticks for the subsession.");
+  if (aExpected > 0) {
+    Assert.equal(payload.processes.parent.scalars["browser.engagement.active_ticks"], aExpected,
+                 "Should record the expected number of active ticks for the subsession, in a scalar.");
+  }
+}
 
 add_task(async function test_setup() {
   do_get_profile();
   // Make sure we don't generate unexpected pings due to pref changes.
   await setEmptyPrefWatchlist();
 });
 
 add_task(async function test_record_activeTicks() {
@@ -44,8 +65,38 @@ add_task(async function test_record_acti
   Services.obs.notifyObservers(null, "user-interaction-active");
   checkActiveTicks(4);
 
   Services.obs.notifyObservers(null, "user-interaction-active");
   checkActiveTicks(5);
 
   await TelemetryController.testShutdown();
 });
+
+add_task({
+  skip_if: () => gIsAndroid
+},
+async function test_subsession_activeTicks() {
+  await TelemetryController.testReset();
+  Telemetry.clearScalars();
+
+  tick(5);
+  checkSessionTicks(5);
+  checkSubsessionTicks(5, true);
+
+  // After clearing the subsession, subsession ticks should be 0 but session
+  // ticks should still be 5.
+  checkSubsessionTicks(0);
+  checkSessionTicks(5);
+
+  tick(1);
+  checkSessionTicks(6);
+  checkSubsessionTicks(1, true);
+
+  checkSubsessionTicks(0);
+  checkSessionTicks(6);
+
+  tick(2);
+  checkSessionTicks(8);
+  checkSubsessionTicks(2);
+
+  await TelemetryController.testShutdown();
+});
--- a/toolkit/content/license.html
+++ b/toolkit/content/license.html
@@ -19,28 +19,28 @@
 #ifdef APP_LICENSE_BLOCK
 #includesubst @APP_LICENSE_BLOCK@
 #endif
     </div>
   </div>
   <div>
     <p>All of the <b>source code</b> to this product is
        available under licenses which are both
-       <a href="http://www.gnu.org/philosophy/free-sw.html">free</a> and
-       <a href="http://www.opensource.org/docs/definition.php">open source</a>.
+       <a href="https://www.gnu.org/philosophy/free-sw.html">free</a> and
+       <a href="https://www.opensource.org/docs/definition.php">open source</a>.
        A URL identifying the specific source code used to create this copy can be found
        on the <a href="about:buildconfig">build configuration page</a>, and you can read
        <a href="https://developer.mozilla.org/en/Mozilla_Source_Code_%28Mercurial%29">instructions
        on how to download and build the code for yourself</a>.
     </p>
 
     <p>More specifically, most of the source code is available under the
        <a href="about:license#mpl">Mozilla Public License 2.0</a> (MPL).
        The MPL has a
-       <a href="http://www.mozilla.org/MPL/2.0/FAQ.html">FAQ</a> to help
+       <a href="https://www.mozilla.org/MPL/2.0/FAQ/">FAQ</a> to help
        you understand it. The remainder of the software which is not
        under the MPL is available under one of a variety of other
        free and open source licenses. Those that require reproduction
        of the license text in the distribution are given below.
        (Note: your copy of this product may not contain code covered by one
        or more of the licenses listed here, depending on the exact product
        and version you choose.)
     </p>
@@ -618,17 +618,17 @@
   notice described in Exhibit B of this License must be attached.</p>
 
   <h2 id="exhibit-a---source-code-form-license-notice">Exhibit A - Source
   Code Form License Notice</h2>
 
   <blockquote>
     <p>This Source Code Form is subject to the terms of the Mozilla Public
     License, v. 2.0. If a copy of the MPL was not distributed with this file,
-    You can obtain one at http://mozilla.org/MPL/2.0/.</p>
+    You can obtain one at https://mozilla.org/MPL/2.0/.</p>
   </blockquote>
 
   <p>If it is not possible or desirable to put the notice in a particular
   file, then You may include the notice in a location (such as a LICENSE file
   in a relevant directory) where a recipient would be likely to look for such
   a notice.</p>
 
   <p>You may add additional accurate notices of copyright ownership.</p>
@@ -644,19 +644,19 @@
 
     <hr>
 
   <h1 id="lgpl">GNU Lesser General Public License 2.1</h1>
 
 <p>This product contains code from the following LGPLed libraries:</p>
 
 <ul>
-<li><a href="http://www.surina.net/soundtouch/">libsoundtouch</a>
-<li><a href="http://libav.org/">libav</a>
-<li><a href="http://ffmpeg.org/">FFmpeg</a>
+<li><a href="https://www.surina.net/soundtouch/">libsoundtouch</a>
+<li><a href="https://libav.org/">Libav</a>
+<li><a href="https://ffmpeg.org/">FFmpeg</a>
 </ul>
 
 <pre>
 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.
 
@@ -1207,17 +1207,17 @@ DAMAGES.
 <p>Some versions of this product contains code from the following LGPLed libraries:</p>
 
 <ul>
 <li><a
 href="https://addons.mozilla.org/en-US/firefox/addon/görans-hemmasnickrade-ordli/">Swedish dictionary</a>
 </ul>
 
 <pre>Copyright &copy; 2007 Free Software Foundation, Inc.
- &lt;<a href="http://fsf.org/">http://fsf.org/</a>&gt;
+ &lt;<a href="https://www.fsf.org/">https://www.fsf.org/</a>&gt;
 
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.</pre>
 
 <p>This version of the GNU Lesser General Public License incorporates
 the terms and conditions of version 3 of the GNU General Public
 License, supplemented by the additional permissions listed below.</p>
 
@@ -1396,17 +1396,17 @@ Library.</p>
     for use with the tracking protection feature. Firefox and such
     blocklists are separate and independent works as described in
     Sections 5 and 6 of this license. Our blocklist is based on one
     originally written by Disconnect.me.</p>
 
 <pre>Version 3, 29 June 2007
 
 Copyright &copy; 2007 Free Software Foundation, Inc.
-&lt;<a href="http://fsf.org/">http://fsf.org/</a>&gt;
+&lt;<a href="https://www.fsf.org/">https://www.fsf.org/</a>&gt;
 
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.</pre>
 
 <h2><a name="preamble"></a>Preamble</h2>
 
 <p>The GNU General Public License is a free, copyleft license for
 software and other kinds of works.</p>
@@ -2047,17 +2047,17 @@ the &ldquo;copyright&rdquo; line and a p
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
+    along with this program.  If not, see &lt;https://www.gnu.org/licenses/&gt;.
 </pre>
 
 <p>Also add information on how to contact you by electronic and paper mail.</p>
 
 <p>If the program does terminal interaction, make it output a short
 notice like this when it starts in an interactive mode:</p>
 
 <pre>    &lt;program&gt;  Copyright (C) &lt;year&gt;  &lt;name of author&gt;
@@ -2068,24 +2068,24 @@ notice like this when it starts in an in
 
 <p>The hypothetical commands `show w' and `show c' should show the appropriate
 parts of the General Public License.  Of course, your program's commands
 might be different; for a GUI interface, you would use an &ldquo;about box&rdquo;.</p>
 
 <p>You should also get your employer (if you work as a programmer) or school,
 if any, to sign a &ldquo;copyright disclaimer&rdquo; for the program, if necessary.
 For more information on this, and how to apply and follow the GNU GPL, see
-&lt;<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>&gt;.</p>
+&lt;<a href="https://www.gnu.org/licenses/">https://www.gnu.org/licenses/</a>&gt;.</p>
 
 <p>The GNU General Public License does not permit incorporating your program
 into proprietary programs.  If your program is a subroutine library, you
 may consider it more useful to permit linking proprietary applications with
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
-&lt;<a href="http://www.gnu.org/philosophy/why-not-lgpl.html">http://www.gnu.org/philosophy/why-not-lgpl.html</a>&gt;.</p>
+&lt;<a href="https://www.gnu.org/philosophy/why-not-lgpl.html">https://www.gnu.org/philosophy/why-not-lgpl.html</a>&gt;.</p>
 
 <hr>
 
     <h1><a id="ACE"></a>ACE License</h1>
 
     <p>This license applies to the file
     <code>media/webrtc/trunk/webrtc/system_wrappers/source/condition_variable_event_win.cc</code>.</p>
 
@@ -2283,17 +2283,17 @@ licences.
 #ifdef MOZ_INSTALL_TRACKING
     <h1><a id="adjust"></a>Adjust SDK License</h1>
 
     <p>This license applies to all files in the directory
     <code>mobile/android/thirdparty/com/adjust/sdk</code>.</p>
 
 <pre>
 Copyright (c) 2012-2014 adjust GmbH,
-http://www.adjust.com
+https://www.adjust.com
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:
@@ -2315,17 +2315,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE
 #endif
     <h1><a id="apache"></a>Apache License 2.0</h1>
 
     <p>This license applies to various files in the Mozilla codebase.</p>
 
 <pre>
                                  Apache License
                            Version 2.0, January 2004
-                        http://www.apache.org/licenses/
+                        https://www.apache.org/licenses/
 
    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 
    1. Definitions.
 
       "License" shall mean the terms and conditions for use, reproduction,
       and distribution as defined by Sections 1 through 9 of this document.
 
@@ -3200,17 +3200,17 @@ publicity, privacy, or moral rights may 
       part of the Estonian Spellchecking Dictionary. The
       shipped versions are under the GNU Lesser General Public License. (This
       code only ships in some localized versions of this product.)</p>
 
 <pre>
 Copyright © Institute of the Estonian Language
 
 E-mail: litsents@eki.ee
-URL: http://www.eki.ee/tarkvara/
+URL: https://www.eki.ee/tarkvara/
 
 The present Licence Agreement gives the user of this Software Product
 (hereinafter: Product) the right to use the Product for whatever purpose
 (incl. distribution, copying, altering, inclusion in other software, and
 selling) on the following conditions:
 
 1. The present Licence Agreement should belong unaltered to each copy ever
    made of this Product;
@@ -3518,17 +3518,17 @@ EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 The contents of this file are taken from Apple80211.h from the iStumbler
-project (http://www.istumbler.net). This project is released under the BSD
+project (https://istumbler.net/). This project is released under the BSD
 license with the following restrictions.
 
 Copyright (c) 02006, Alf Watt (alf@istumbler.net). All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 
@@ -3929,17 +3929,17 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SU
 
     <hr>
 
     <h1><a id="jquery"></a>jQuery License</h1>
 
     <p>This license applies to all copies of jQuery in the code.</p>
 
 <pre>
-Copyright (c) 2010 John Resig, http://jquery.com/
+Copyright (c) 2010 John Resig, https://jquery.com/
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:
@@ -4462,17 +4462,17 @@ SUCH DAMAGE.
 
     <p>This license applies to some of the code in
     <code>devtools/client/shared/vendor/lodash.js</code>.</p>
 
 <pre>
 Copyright JS Foundation and other contributors <https://js.foundation/>
 
 Based on Underscore.js, copyright Jeremy Ashkenas,
-DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
+DocumentCloud and Investigative Reporters & Editors <https://underscorejs.org/>
 
 This software consists of voluntary contributions made by many
 individuals. For exact contribution history, see the revision history
 available at https://github.com/lodash/lodash
 
 The following license applies to all parts of this software except as
 documented below:
 
@@ -4498,17 +4498,17 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING 
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 ====
 
 Copyright and related rights for sample code are waived via CC0. Sample
 code is defined as all source code displayed within the prose of the
 documentation.
 
-CC0: http://creativecommons.org/publicdomain/zero/1.0/
+CC0: https://creativecommons.org/publicdomain/zero/1.0/
 
 ====
 
 Files located in the node_modules and vendor directories are externally
 maintained libraries used by this software which have their own
 licenses; we recommend you read them, as their terms may differ from the
 terms above.
 
@@ -6183,17 +6183,17 @@ THE SOFTWARE.
     and <code>intl/tzdata</code> directories and certain files in
     the <code>js/src/vm</code> directory.</p>
     </p>
 
 <pre>
 COPYRIGHT AND PERMISSION NOTICE
 
 Copyright © 1991-2016 Unicode, Inc. All rights reserved.
-Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
+Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of the Unicode data files and any associated documentation
 (the "Data Files") or Unicode software and any associated documentation
 (the "Software") to deal in the Data Files or Software
 without restriction, including without limitation the rights to use,
 copy, modify, merge, publish, distribute, and/or sell copies of
 the Data Files or Software, and to permit persons to whom the Data Files
@@ -6264,17 +6264,17 @@ property of their respective owners.
 
 2. Chinese/Japanese Word Break Dictionary Data (cjdict.txt)
 
  #     The Google Chrome software developed by Google is licensed under
  # the BSD license. Other software included in this distribution is
  # provided under other licenses, as set forth below.
  #
  #  The BSD License
- #  http://opensource.org/licenses/bsd-license.php
+ #  https://opensource.org/licenses/bsd-license.php
  #  Copyright (C) 2006-2008, Google Inc.
  #
  #  All rights reserved.
  #
  #  Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions are met:
  #
  #  Redistributions of source code must retain the above copyright notice,
@@ -6466,19 +6466,19 @@ 2. Chinese/Japanese Word Break Dictionar
  #
  #  ---------------COPYING.ipadic-----END----------------------------------
 
 3. Lao Word Break Dictionary Data (laodict.txt)
 
  #  Copyright (c) 2013 International Business Machines Corporation
  #  and others. All Rights Reserved.
  #
- # Project: http://code.google.com/p/lao-dictionary/
- # Dictionary: http://lao-dictionary.googlecode.com/git/Lao-Dictionary.txt
- # License: http://lao-dictionary.googlecode.com/git/Lao-Dictionary-LICENSE.txt
+ # Project: https://code.google.com/p/lao-dictionary/
+ # Dictionary: https://lao-dictionary.googlecode.com/git/Lao-Dictionary.txt
+ # License: https://lao-dictionary.googlecode.com/git/Lao-Dictionary-LICENSE.txt
  #              (copied below)
  #
  #  This file is derived from the above dictionary, with slight
  #  modifications.
  #  ----------------------------------------------------------------------
  #  Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell.
  #  All rights reserved.
  #
@@ -7040,55 +7040,55 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
     <h1><a id="other-notices"></a>Other Required Notices</h1>
 
     <ul>
       <li>This software is based in part on the work of the Independent
           JPEG Group.</li>
       <li>Portions of the OS/2 and Android versions
           of this software are copyright &copy;1996-2012
-          <a href="http://www.freetype.org/">The FreeType Project</a>.
+          <a href="https://www.freetype.org/">The FreeType Project</a>.
           All rights reserved.</li>
     </ul>
 
 
     <hr>
 
     <h1><a id="optional-notices"></a>Optional Notices</h1>
 
     <p>Some permissive software licenses request but do not require an
     acknowledgement of the use of their software. We are very grateful
     to the following people and projects for their contributions to
     this product:</p>
 
     <ul>
-      <li>The <a href="http://www.zlib.net/">zlib</a> compression library
+      <li>The <a href="https://www.zlib.net/">zlib</a> compression library
           (Jean-loup Gailly, Mark Adler and team)</li>
       <li>The <a href="http://www.bzip.org/">bzip2</a> compression library
           (Julian Seward)</li>
       <li>The <a href="http://www.libpng.org/pub/png/">libpng</a> graphics library
           (Glenn Randers-Pehrson and team)</li>
-      <li>The <a href="http://www.sqlite.org/">sqlite</a> database engine
+      <li>The <a href="https://www.sqlite.org/">sqlite</a> database engine
           (D. Richard Hipp and team)</li>
       <li>The <a href="http://nsis.sourceforge.net/">Nullsoft Scriptable Install System</a>
           (Amir Szekely and team)</li>
-      <li>The <a href="http://mattmccutchen.net/bigint/">C++ Big Integer Library</a>
+      <li>The <a href="https://mattmccutchen.net/bigint/">C++ Big Integer Library</a>
           (Matt McCutchen)</li>
     </ul>
 
 
 
 #ifdef XP_WIN
 
     <hr>
 
     <h1><a id="proprietary-notices"></a>Proprietary Operating System Components</h1>
 
     <p>Under some circumstances, under our
-    <a href="http://www.mozilla.org/foundation/licensing/binary-components/">binary components policy</a>,
+    <a href="https://www.mozilla.org/foundation/licensing/binary-components/">binary components policy</a>,
     Mozilla may decide to include additional
     operating system vendor code with the installer of our products designed
     for that vendor's proprietary platform, to make our products work well on
     that specific operating system. The following license statements
     apply to such inclusions.</p>
 
     <h2><a id="directx"></a>Microsoft Windows: Terms for 'Microsoft Distributable Code'</h2>
 
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -2743,17 +2743,17 @@ nsNativeThemeCocoa::ComputeScrollbarPara
      scrollbarFrame->StyleDisplay()->mAppearance == StyleAppearance::ScrollbarSmall);
   params.rtl = IsFrameRTL(aFrame);
   params.horizontal = aIsHorizontal;
   params.onDarkBackground = IsDarkBackground(aFrame);
   // Don't use custom scrollbars for overlay scrollbars since they are
   // generally good enough for use cases of custom scrollbars.
   if (!params.overlay) {
     ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
-    if (style->StyleUserInterface()->HasCustomScrollbars()) {
+    if (style->StyleUI()->HasCustomScrollbars()) {
       params.custom = true;
       params.trackColor =
         GetScrollbarTrackColor(style, &GetAutoScrollbarTrackColor);
       params.faceColor =
         GetScrollbarFaceColor(style, &GetAutoScrollbarFaceColor);
     }
   }
   return params;
--- a/widget/nsNativeTheme.cpp
+++ b/widget/nsNativeTheme.cpp
@@ -844,35 +844,33 @@ GetOpaqueBackgroundColor(ComputedStyle* 
   // Compose white background with the background color.
   return NS_ComposeColors(NS_RGB(255, 255, 255), color);
 }
 
 nscolor
 nsNativeTheme::GetScrollbarFaceColor(ComputedStyle* aStyle,
                                      AutoColorGetter aAutoGetter)
 {
-  StyleComplexColor complexColor =
-    aStyle->StyleUserInterface()->mScrollbarFaceColor;
+  StyleComplexColor complexColor = aStyle->StyleUI()->mScrollbarFaceColor;
   if (complexColor.IsAuto()) {
     return aAutoGetter(aStyle);
   }
   nscolor color = complexColor.CalcColor(aStyle);
   if (NS_GET_A(color) == 255) {
     return color;
   }
   nscolor bgColor = GetOpaqueBackgroundColor(aStyle);
   return NS_ComposeColors(bgColor, color);
 }
 
 nscolor
 nsNativeTheme::GetScrollbarTrackColor(ComputedStyle* aStyle,
                                       AutoColorGetter aAutoGetter)
 {
-  StyleComplexColor complexColor =
-    aStyle->StyleUserInterface()->mScrollbarTrackColor;
+  StyleComplexColor complexColor = aStyle->StyleUI()->mScrollbarTrackColor;
   nscolor color;
   if (complexColor.IsAuto()) {
     color = aAutoGetter(aStyle);
   } else {
     color = complexColor.CalcColor(aStyle);
   }
   if (NS_GET_A(color) == 255) {
     return color;
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -1554,17 +1554,17 @@ nsNativeThemeWin::DrawWidgetBackground(g
 {
   if (aWidgetType == StyleAppearance::MenulistButton &&
       StaticPrefs::layout_css_webkit_appearance_enabled()) {
     aWidgetType = StyleAppearance::Menulist;
   }
 
   if (IsWidgetScrollbarPart(aWidgetType)) {
     ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
-    if (style->StyleUserInterface()->HasCustomScrollbars()) {
+    if (style->StyleUI()->HasCustomScrollbars()) {
       return DrawCustomScrollbarPart(aContext, aFrame, style,
                                      aWidgetType, aRect, aDirtyRect);
     }
   }
 
   HANDLE theme = GetTheme(aWidgetType);
   if (!theme)
     return ClassicDrawWidgetBackground(aContext, aFrame, aWidgetType, aRect, aDirtyRect); 
@@ -3187,17 +3187,17 @@ nsresult nsNativeThemeWin::ClassicGetThe
         aState |= DFCS_INACTIVE;
       else if (IsOpenButton(aFrame))
         aState |= DFCS_PUSHED;
       else if (IsCheckedButton(aFrame))
         aState |= DFCS_CHECKED;
       else {
         if (contentState.HasAllStates(NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_HOVER)) {
           aState |= DFCS_PUSHED;
-          const nsStyleUserInterface *uiData = aFrame->StyleUserInterface();
+          const nsStyleUI *uiData = aFrame->StyleUI();
           // The down state is flat if the button is focusable
           if (uiData->mUserFocus == StyleUserFocus::Normal) {
             if (!aFrame->GetContent()->IsHTMLElement())
               aState |= DFCS_FLAT;
 
             aFocused = true;
           }
         }
@@ -4226,18 +4226,18 @@ GetScrollbarArrowColor(nscolor aTrackCol
 nsresult
 nsNativeThemeWin::DrawCustomScrollbarPart(gfxContext* aContext,
                                           nsIFrame* aFrame,
                                           ComputedStyle* aStyle,
                                           WidgetType aWidgetType,
                                           const nsRect& aRect,
                                           const nsRect& aClipRect)
 {
-  MOZ_ASSERT(!aStyle->StyleUserInterface()->mScrollbarFaceColor.IsAuto() ||
-             !aStyle->StyleUserInterface()->mScrollbarTrackColor.IsAuto());
+  MOZ_ASSERT(!aStyle->StyleUI()->mScrollbarFaceColor.IsAuto() ||
+             !aStyle->StyleUI()->mScrollbarTrackColor.IsAuto());
 
   gfxRect tr(aRect.X(), aRect.Y(), aRect.Width(), aRect.Height()),
           dr(aClipRect.X(), aClipRect.Y(),
              aClipRect.Width(), aClipRect.Height());
 
   nscolor trackColor =
     GetScrollbarTrackColor(aStyle, &GetScrollbarTrackColorForAuto);
   HBRUSH dcBrush = (HBRUSH) GetStockObject(DC_BRUSH);