Merge mozilla-central to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 23 Sep 2016 12:38:03 +0200
changeset 315048 c4d91d17c8ed2e385f4a4a3d97f861eee722626f
parent 314986 589d63647e0bebe187552e3ff9b6b82ce4a5f372 (current diff)
parent 315047 60cc643978c7020926fe4145761e26945fcd5c37 (diff)
child 315049 52459cfd15765aa82ff26501b9c1a56272d49f0d
push id82041
push usercbook@mozilla.com
push dateFri, 23 Sep 2016 10:38:40 +0000
treeherdermozilla-inbound@c4d91d17c8ed [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone52.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 mozilla-central to mozilla-inbound
browser/extensions/webcompat/test/browser.ini
browser/extensions/webcompat/test/browser_webcompat_stub_check.js
browser/modules/PanelFrame.jsm
devtools/client/.babelrc
layout/base/nsPresShell.cpp
layout/base/nsRefreshDriver.cpp
services/sync/tests/tps/test_privbrw_formdata.js
testing/marionette/harness/marionette/tests/print-manifest-dirs.py
toolkit/components/autocomplete/tests/unit/test_hiddenResult.js
toolkit/components/autocomplete/tests/unit/test_popupSelectionVsDefaultCompleteValue.js
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -286,24 +286,17 @@ SocialShare = {
         this.panel.hidePopup();
         break;
     }
   },
 
   handleEvent: function(event) {
     switch (event.type) {
       case "load": {
-        let iframe = this.iframe;
-        iframe.parentNode.removeAttribute("loading");
-        // to support standard share endpoints mimick window.open by setting
-        // window.opener, some share endpoints rely on w.opener to know they
-        // should close the window when done.
-        iframe.contentWindow.opener = iframe.contentWindow;
-        this.messageManager.sendAsyncMessage("Social:HookWindowCloseForPanelClose");
-        this.messageManager.sendAsyncMessage("Social:DisableDialogs", {});
+        this.iframe.parentNode.removeAttribute("loading");
         if (this.currentShare)
           SocialShare.messageManager.sendAsyncMessage("Social:OpenGraphData", this.currentShare);
       }
     }
   },
 
   getSelectedProvider: function() {
     let provider;
--- a/browser/base/content/social-content.js
+++ b/browser/base/content/social-content.js
@@ -1,214 +1,102 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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/. */
 
-/* This content script should work in any browser or iframe and should not
- * depend on the frame being contained in tabbrowser. */
+/* This content script is intended for use by iframes in the share panel. */
 
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-// Tie `content` to this frame scripts' global scope explicitly. If we don't, then
-// `content` might be out of eval's scope and GC'ed before this script is done.
-// See bug 1229195 for empirical proof.
-var gContent = content;
-
 // social frames are always treated as app tabs
 docShell.isAppTab = true;
-var gHookedWindowCloseForPanelClose = false;
 
-var gDOMContentLoaded = false;
 addEventListener("DOMContentLoaded", function(event) {
-  if (event.target == content.document) {
-    gDOMContentLoaded = true;
-    sendAsyncMessage("DOMContentLoaded");
+  if (event.target != content.document)
+    return;
+  // Some share panels (e.g. twitter and facebook) check content.opener, and if
+  // it doesn't exist they act like they are in a browser tab.  We want them to
+  // act like they are in a dialog (which is the typical case).
+  if (content && !content.opener) {
+    content.opener = content;
   }
-});
-addEventListener("unload", function(event) {
-  if (event.target == content.document) {
-    gDOMContentLoaded = false;
-    gHookedWindowCloseForPanelClose = false;
-  }
-}, true);
-
-var gDOMTitleChangedByUs = false;
-addEventListener("DOMTitleChanged", function(e) {
-  if (!gDOMTitleChangedByUs) {
-    sendAsyncMessage("Social:DOMTitleChanged", {
-      title: e.target.title
-    });
-  }
-  gDOMTitleChangedByUs = false;
+  hookWindowClose();
+  disableDialogs();
 });
 
 addMessageListener("Social:OpenGraphData", (message) => {
   let ev = new content.CustomEvent("OpenGraphData", { detail: JSON.stringify(message.data) });
   content.dispatchEvent(ev);
 });
 
-addMessageListener("Social:ClearFrame", (message) => {
+addMessageListener("Social:ClearFrame", () => {
   docShell.createAboutBlankContentViewer(null);
 });
 
+addEventListener("DOMWindowClose", (evt) => {
+  // preventDefault stops the default window.close() function being called,
+  // which doesn't actually close anything but causes things to get into
+  // a bad state (an internal 'closed' flag is set and debug builds start
+  // asserting as the window is used.).
+  // None of the windows we inject this API into are suitable for this
+  // default close behaviour, so even if we took no action above, we avoid
+  // the default close from doing anything.
+  evt.preventDefault();
+
+  // Tells the SocialShare class to close the panel
+  sendAsyncMessage("Social:DOMWindowClose");
+});
+
+function hookWindowClose() {
+  // Allow scripts to close the "window".  Because we are in a panel and not
+  // in a full dialog, the DOMWindowClose listener above will only receive the
+  // event if we do this.
+  let dwu = content.QueryInterface(Ci.nsIInterfaceRequestor)
+     .getInterface(Ci.nsIDOMWindowUtils);
+  dwu.allowScriptsToClose();
+}
+
+function disableDialogs() {
+  let windowUtils = content.QueryInterface(Ci.nsIInterfaceRequestor).
+                    getInterface(Ci.nsIDOMWindowUtils);
+  windowUtils.disableDialogs();
+}
+
 // Error handling class used to listen for network errors in the social frames
 // and replace them with a social-specific error page
 const SocialErrorListener = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
                                          Ci.nsIWebProgressListener,
                                          Ci.nsISupportsWeakReference,
                                          Ci.nsISupports]),
 
   defaultTemplate: "about:socialerror?mode=tryAgainOnly&url=%{url}&origin=%{origin}",
   urlTemplate: null,
 
   init() {
-    addMessageListener("Loop:MonitorPeerConnectionLifecycle", this);
-    addMessageListener("Loop:GetAllWebrtcStats", this);
-    addMessageListener("Social:CustomEvent", this);
-    addMessageListener("Social:EnsureFocus", this);
-    addMessageListener("Social:EnsureFocusElement", this);
-    addMessageListener("Social:HookWindowCloseForPanelClose", this);
-    addMessageListener("Social:ListenForEvents", this);
-    addMessageListener("Social:SetDocumentTitle", this);
     addMessageListener("Social:SetErrorURL", this);
-    addMessageListener("Social:DisableDialogs", this);
-    addMessageListener("Social:WaitForDocumentVisible", this);
-    addMessageListener("WaitForDOMContentLoaded", this);
     let webProgress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                               .getInterface(Components.interfaces.nsIWebProgress);
     webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST |
                                           Ci.nsIWebProgress.NOTIFY_LOCATION);
   },
 
   receiveMessage(message) {
-    let document = content.document;
-
     switch (message.name) {
-      case "Loop:GetAllWebrtcStats":
-        content.WebrtcGlobalInformation.getAllStats(allStats => {
-          content.WebrtcGlobalInformation.getLogging("", logs => {
-            sendAsyncMessage("Loop:GetAllWebrtcStats", {
-              allStats: allStats,
-              logs: logs
-            });
-          });
-        }, message.data.peerConnectionID);
-        break;
-      case "Loop:MonitorPeerConnectionLifecycle":
-        let ourID = content.QueryInterface(Ci.nsIInterfaceRequestor)
-          .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
-
-        let onPCLifecycleChange = (pc, winID, type) => {
-          if (winID != ourID) {
-            return;
-          }
-
-          sendAsyncMessage("Loop:PeerConnectionLifecycleChange", {
-            iceConnectionState: pc.iceConnectionState,
-            locationHash: content.location.hash,
-            peerConnectionID: pc.id,
-            type: type
-          });
-        };
-
-        let pc_static = new content.RTCPeerConnectionStatic();
-        pc_static.registerPeerConnectionLifecycleCallback(onPCLifecycleChange);
-        break;
-      case "Social:CustomEvent":
-        let ev = new content.CustomEvent(message.data.name, message.data.detail ?
-          { detail: message.data.detail } : null);
-        content.dispatchEvent(ev);
-        break;
-      case "Social:EnsureFocus":
-        Services.focus.focusedWindow = content;
-        sendAsyncMessage("Social:FocusEnsured");
-        break;
-      case "Social:EnsureFocusElement":
-        let fm = Services.focus;
-        fm.moveFocus(document.defaultView, null, fm.MOVEFOCUS_FIRST, fm.FLAG_NOSCROLL);
-        sendAsyncMessage("Social:FocusEnsured");
-        break;
-      case "Social:HookWindowCloseForPanelClose":
-        if (gHookedWindowCloseForPanelClose) {
-          break;
-        }
-        gHookedWindowCloseForPanelClose = true;
-        // We allow window.close() to close the panel, so add an event handler for
-        // this, then cancel the event (so the window itself doesn't die) and
-        // close the panel instead.
-        // However, this is typically affected by the dom.allow_scripts_to_close_windows
-        // preference, but we can avoid that check by setting a flag on the window.
-        let dwu = content.QueryInterface(Ci.nsIInterfaceRequestor)
-           .getInterface(Ci.nsIDOMWindowUtils);
-        dwu.allowScriptsToClose();
-
-        content.addEventListener("DOMWindowClose", function _mozSocialDOMWindowClose(evt) {
-          // preventDefault stops the default window.close() function being called,
-          // which doesn't actually close anything but causes things to get into
-          // a bad state (an internal 'closed' flag is set and debug builds start
-          // asserting as the window is used.).
-          // None of the windows we inject this API into are suitable for this
-          // default close behaviour, so even if we took no action above, we avoid
-          // the default close from doing anything.
-          evt.preventDefault();
-
-          sendAsyncMessage("Social:DOMWindowClose");
-        }, true);
-        break;
-      case "Social:ListenForEvents":
-        for (let eventName of message.data.eventNames) {
-          content.addEventListener(eventName, this);
-        }
-        break;
-      case "Social:SetDocumentTitle":
-        let title = message.data.title;
-        if (title && (title = title.trim())) {
-          gDOMTitleChangedByUs = true;
-          document.title = title;
-        }
-        break;
       case "Social:SetErrorURL":
         // Either a url or null to reset to default template.
         this.urlTemplate = message.data.template;
         break;
-      case "Social:WaitForDocumentVisible":
-        if (!document.hidden) {
-          sendAsyncMessage("Social:DocumentVisible");
-          break;
-        }
-
-        document.addEventListener("visibilitychange", function onVisibilityChanged() {
-          document.removeEventListener("visibilitychange", onVisibilityChanged);
-          sendAsyncMessage("Social:DocumentVisible");
-        });
-        break;
-      case "Social:DisableDialogs":
-        let windowUtils = content.QueryInterface(Ci.nsIInterfaceRequestor).
-                          getInterface(Ci.nsIDOMWindowUtils);
-        windowUtils.disableDialogs();
-        break;
-      case "WaitForDOMContentLoaded":
-        if (gDOMContentLoaded) {
-          sendAsyncMessage("DOMContentLoaded");
-        }
-        break;
     }
   },
 
-  handleEvent: function(event) {
-    sendAsyncMessage("Social:CustomEvent", {
-      name: event.type
-    });
-  },
-
   setErrorPage() {
     // if this is about:providerdirectory, use the directory iframe
     let frame = docShell.chromeEventHandler;
     let origin = frame.getAttribute("origin");
     let src = frame.getAttribute("src");
     if (src == "about:providerdirectory") {
       frame = content.document.getElementById("activation-frame");
       src = frame.getAttribute("src");
--- a/browser/components/extensions/ext-contextMenus.js
+++ b/browser/components/extensions/ext-contextMenus.js
@@ -169,33 +169,34 @@ var gMenuBuilder = {
     if (!item.enabled) {
       element.setAttribute("disabled", "true");
     }
 
     element.addEventListener("command", event => {  // eslint-disable-line mozilla/balanced-listeners
       if (event.target !== event.currentTarget) {
         return;
       }
+      const wasChecked = item.checked;
       if (item.type == "checkbox") {
         item.checked = !item.checked;
       } else if (item.type == "radio") {
         // Deselect all radio items in the current radio group.
         for (let child of item.parent.children) {
           if (child.type == "radio" && child.groupName == item.groupName) {
             child.checked = false;
           }
         }
         // Select the clicked radio item.
         item.checked = true;
       }
 
       item.tabManager.addActiveTabPermission();
 
       let tab = item.tabManager.convert(contextData.tab);
-      let info = item.getClickInfo(contextData, event);
+      let info = item.getClickInfo(contextData, wasChecked);
       item.extension.emit("webext-contextmenu-menuitem-click", info, tab);
       if (item.onclick) {
         runSafe(item.extContext, item.onclick, info, tab);
       }
     });
 
     return element;
   },
@@ -394,46 +395,51 @@ MenuItem.prototype = {
 
     let menuMap = gContextMenuMap.get(this.extension);
     menuMap.delete(this.id);
     if (this.root == this) {
       gRootItems.delete(this.extension);
     }
   },
 
-  getClickInfo(contextData, event) {
+  getClickInfo(contextData, wasChecked) {
     let mediaType;
     if (contextData.onVideo) {
       mediaType = "video";
     }
     if (contextData.onAudio) {
       mediaType = "audio";
     }
     if (contextData.onImage) {
       mediaType = "image";
     }
 
     let info = {
       menuItemId: this.id,
+      editable: contextData.onEditableArea,
     };
 
     function setIfDefined(argName, value) {
-      if (value) {
+      if (value !== undefined) {
         info[argName] = value;
       }
     }
 
     setIfDefined("parentMenuItemId", this.parentId);
     setIfDefined("mediaType", mediaType);
     setIfDefined("linkUrl", contextData.linkUrl);
     setIfDefined("srcUrl", contextData.srcUrl);
     setIfDefined("pageUrl", contextData.pageUrl);
     setIfDefined("frameUrl", contextData.frameUrl);
     setIfDefined("selectionText", contextData.selectionText);
-    setIfDefined("editable", contextData.onEditableArea);
+
+    if ((this.type === "checkbox") || (this.type === "radio")) {
+      info.checked = this.checked;
+      info.wasChecked = wasChecked;
+    }
 
     return info;
   },
 
   enabledForContext(contextData) {
     let contexts = getContexts(contextData);
     if (!this.contexts.some(n => contexts.has(n))) {
       return false;
--- a/browser/components/extensions/ext-utils.js
+++ b/browser/components/extensions/ext-utils.js
@@ -240,16 +240,17 @@ class BasePopup {
   createBrowser(viewNode, popupURL = null) {
     let document = viewNode.ownerDocument;
     this.browser = document.createElementNS(XUL_NS, "browser");
     this.browser.setAttribute("type", "content");
     this.browser.setAttribute("disableglobalhistory", "true");
     this.browser.setAttribute("transparent", "true");
     this.browser.setAttribute("class", "webextension-popup-browser");
     this.browser.setAttribute("webextension-view-type", "popup");
+    this.browser.setAttribute("tooltip", "aHTMLTooltip");
 
     // We only need flex sizing for the sake of the slide-in sub-views of the
     // main menu panel, so that the browser occupies the full width of the view,
     // and also takes up any extra height that's available to it.
     this.browser.setAttribute("flex", "1");
 
     // Note: When using noautohide panels, the popup manager will add width and
     // height attributes to the panel, breaking our resize code, if the browser
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus.js
+++ b/browser/components/extensions/test/browser/browser_ext_contextMenus.js
@@ -65,17 +65,17 @@ add_task(function* () {
         browser.test.sendMessage("browser.contextMenus.onClicked", {info, tab});
       });
 
       browser.contextMenus.create({
         contexts: ["all"],
         type: "separator",
       });
 
-      let contexts = ["page", "selection", "image"];
+      let contexts = ["page", "selection", "image", "editable"];
       for (let i = 0; i < contexts.length; i++) {
         let context = contexts[i];
         let title = context;
         browser.contextMenus.create({
           title: title,
           contexts: [context],
           id: "ext-" + context,
           onclick: genericOnClick,
@@ -139,22 +139,23 @@ add_task(function* () {
   yield extension.startup();
   yield extension.awaitFinish("contextmenus");
 
   let expectedClickInfo = {
     menuItemId: "ext-image",
     mediaType: "image",
     srcUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/ctxmenu-image.png",
     pageUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html",
+    editable: false,
   };
 
   function checkClickInfo(result) {
     for (let i of Object.keys(expectedClickInfo)) {
       is(result.info[i], expectedClickInfo[i],
-         "click info " + i + " expected to be: " + expectedClickInfo[i] + " but was: " + info[i]);
+         "click info " + i + " expected to be: " + expectedClickInfo[i] + " but was: " + result.info[i]);
     }
     is(expectedClickInfo.pageSrc, result.tab.url);
   }
 
   let extensionMenuRoot = yield openExtensionContextMenu();
 
   // Check some menu items
   let items = extensionMenuRoot.getElementsByAttribute("label", "image");
@@ -175,16 +176,40 @@ add_task(function* () {
   // Click on ext-image item and check the click results
   yield closeExtensionContextMenu(image);
 
   let result = yield extension.awaitMessage("onclick");
   checkClickInfo(result);
   result = yield extension.awaitMessage("browser.contextMenus.onClicked");
   checkClickInfo(result);
 
+
+  // Test "editable" context and OnClick data property.
+  extensionMenuRoot = yield openExtensionContextMenu("#edit-me");
+
+  // Check some menu items.
+  items = extensionMenuRoot.getElementsByAttribute("label", "editable");
+  is(items.length, 1, "contextMenu item for text input element was found (context=editable)");
+  let editable = items[0];
+
+  // Click on ext-editable item and check the click results.
+  yield closeExtensionContextMenu(editable);
+
+  expectedClickInfo = {
+    menuItemId: "ext-editable",
+    pageUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html",
+    editable: true,
+  };
+
+  result = yield extension.awaitMessage("onclick");
+  checkClickInfo(result);
+  result = yield extension.awaitMessage("browser.contextMenus.onClicked");
+  checkClickInfo(result);
+
+
   // Select some text
   yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* (arg) {
     let doc = content.document;
     let range = doc.createRange();
     let selection = content.getSelection();
     selection.removeAllRanges();
     let textNode = doc.getElementById("img1").previousSibling;
     range.setStart(textNode, 0);
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_checkboxes.js
+++ b/browser/components/extensions/test/browser/browser_ext_contextMenus_checkboxes.js
@@ -9,16 +9,21 @@ add_task(function* () {
   gBrowser.selectedTab = tab1;
 
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
       "permissions": ["contextMenus"],
     },
 
     background: function() {
+      // Report onClickData info back.
+      browser.contextMenus.onClicked.addListener(info => {
+        browser.test.sendMessage("contextmenus-click", info);
+      });
+
       browser.contextMenus.create({
         title: "Checkbox",
         type: "checkbox",
       });
 
       browser.contextMenus.create({
         type: "separator",
       });
@@ -48,27 +53,44 @@ add_task(function* () {
 
     is(checkboxItems[0].hasAttribute("checked"), expectedStates[0], `checkbox item 1 has state (checked=${expectedStates[0]})`);
     is(checkboxItems[1].hasAttribute("checked"), expectedStates[1], `checkbox item 2 has state (checked=${expectedStates[1]})`);
     is(checkboxItems[2].hasAttribute("checked"), expectedStates[2], `checkbox item 3 has state (checked=${expectedStates[2]})`);
 
     return extensionMenuRoot.getElementsByAttribute("type", "checkbox");
   }
 
+  function confirmOnClickData(onClickData, id, was, checked) {
+    is(onClickData.wasChecked, was, `checkbox item ${id} was ${was ? "" : "not "}checked before the click`);
+    is(onClickData.checked, checked, `checkbox item ${id} is ${checked ? "" : "not "}checked after the click`);
+  }
+
   let extensionMenuRoot = yield openExtensionContextMenu();
   let items = confirmCheckboxStates(extensionMenuRoot, [false, true, false]);
   yield closeExtensionContextMenu(items[0]);
 
+  let result = yield extension.awaitMessage("contextmenus-click");
+  confirmOnClickData(result, 1, false, true);
+
   extensionMenuRoot = yield openExtensionContextMenu();
   items = confirmCheckboxStates(extensionMenuRoot, [true, true, false]);
   yield closeExtensionContextMenu(items[2]);
 
+  result = yield extension.awaitMessage("contextmenus-click");
+  confirmOnClickData(result, 3, false, true);
+
   extensionMenuRoot = yield openExtensionContextMenu();
   items = confirmCheckboxStates(extensionMenuRoot, [true, true, true]);
   yield closeExtensionContextMenu(items[0]);
 
+  result = yield extension.awaitMessage("contextmenus-click");
+  confirmOnClickData(result, 1, true, false);
+
   extensionMenuRoot = yield openExtensionContextMenu();
   items = confirmCheckboxStates(extensionMenuRoot, [false, true, true]);
   yield closeExtensionContextMenu(items[2]);
 
+  result = yield extension.awaitMessage("contextmenus-click");
+  confirmOnClickData(result, 3, true, false);
+
   yield extension.unload();
   yield BrowserTestUtils.removeTab(tab1);
 });
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_radioGroups.js
+++ b/browser/components/extensions/test/browser/browser_ext_contextMenus_radioGroups.js
@@ -9,16 +9,21 @@ add_task(function* () {
   gBrowser.selectedTab = tab1;
 
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
       "permissions": ["contextMenus"],
     },
 
     background: function() {
+      // Report onClickData info back.
+      browser.contextMenus.onClicked.addListener(info => {
+        browser.test.sendMessage("contextmenus-click", info);
+      });
+
       browser.contextMenus.create({
         title: "radio-group-1",
         type: "radio",
         checked: true,
       });
 
       browser.contextMenus.create({
         type: "separator",
@@ -52,27 +57,44 @@ add_task(function* () {
 
     is(radioGroup1[0].hasAttribute("checked"), expectedStates[0], `radio item 1 has state (checked=${expectedStates[0]})`);
     is(radioGroup2[0].hasAttribute("checked"), expectedStates[1], `radio item 2 has state (checked=${expectedStates[1]})`);
     is(radioGroup2[1].hasAttribute("checked"), expectedStates[2], `radio item 3 has state (checked=${expectedStates[2]})`);
 
     return extensionMenuRoot.getElementsByAttribute("type", "radio");
   }
 
+  function confirmOnClickData(onClickData, id, was, checked) {
+    is(onClickData.wasChecked, was, `radio item ${id} was ${was ? "" : "not "}checked before the click`);
+    is(onClickData.checked, checked, `radio item ${id} is ${checked ? "" : "not "}checked after the click`);
+  }
+
   let extensionMenuRoot = yield openExtensionContextMenu();
   let items = confirmRadioGroupStates(extensionMenuRoot, [true, false, false]);
   yield closeExtensionContextMenu(items[1]);
 
+  let result = yield extension.awaitMessage("contextmenus-click");
+  confirmOnClickData(result, 2, false, true);
+
   extensionMenuRoot = yield openExtensionContextMenu();
   items = confirmRadioGroupStates(extensionMenuRoot, [true, true, false]);
   yield closeExtensionContextMenu(items[2]);
 
-  extensionMenuRoot = yield openExtensionContextMenu();
-  items = confirmRadioGroupStates(extensionMenuRoot, [true, false, true]);
-  yield closeExtensionContextMenu(items[0]);
+  result = yield extension.awaitMessage("contextmenus-click");
+  confirmOnClickData(result, 3, false, true);
 
   extensionMenuRoot = yield openExtensionContextMenu();
   items = confirmRadioGroupStates(extensionMenuRoot, [true, false, true]);
   yield closeExtensionContextMenu(items[0]);
 
+  result = yield extension.awaitMessage("contextmenus-click");
+  confirmOnClickData(result, 1, true, true);
+
+  extensionMenuRoot = yield openExtensionContextMenu();
+  items = confirmRadioGroupStates(extensionMenuRoot, [true, false, true]);
+  yield closeExtensionContextMenu(items[0]);
+
+  result = yield extension.awaitMessage("contextmenus-click");
+  confirmOnClickData(result, 1, true, true);
+
   yield extension.unload();
   yield BrowserTestUtils.removeTab(tab1);
 });
--- a/browser/components/extensions/test/browser/context.html
+++ b/browser/components/extensions/test/browser/context.html
@@ -9,10 +9,14 @@
     <a href="some-link" id="link1">Some link</a>
   </p>
 
   <p>
     <a href="image-around-some-link">
       <img src="ctxmenu-image.png" id="img-wrapped-in-link">
     </a>
   </p>
+
+  <p>
+    <input type="text" id="edit-me">
+  </p>
   </body>
 </html>
--- a/browser/components/originattributes/test/browser/browser.ini
+++ b/browser/components/originattributes/test/browser/browser.ini
@@ -1,14 +1,16 @@
 [DEFAULT]
 skip-if = buildapp == "mulet"
 tags = usercontextid firstpartyisolation originattributes
 support-files =
   dummy.html
   file_firstPartyBasic.html
+  file_sharedworker.html
+  file_sharedworker.js
   head.js
   test.js
   test.js^headers^
   test.html
   test2.html
   test2.js
   test2.js^headers^
   test_firstParty.html
@@ -21,8 +23,9 @@ support-files =
   window.html
   worker_blobify.js
   worker_deblobify.js
 
 [browser_firstPartyIsolation.js]
 [browser_localStorageIsolation.js]
 [browser_blobURLIsolation.js]
 [browser_imageCacheIsolation.js]
+[browser_sharedworker.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/browser_sharedworker.js
@@ -0,0 +1,26 @@
+/**
+ * Bug 1264593 - A test case for the shared worker by first party isolation.
+ */
+
+const TEST_DOMAIN = "http://example.net/";
+const TEST_PATH = TEST_DOMAIN + "browser/browser/components/originattributes/test/browser/";
+const TEST_PAGE = TEST_PATH + "file_sharedworker.html";
+
+function* getResultFromSharedworker(aBrowser) {
+  let response = yield ContentTask.spawn(aBrowser, null, function* () {
+    let worker = new content.SharedWorker("file_sharedworker.js", "isolationSharedWorkerTest");
+
+    let result = yield new Promise(resolve => {
+      worker.port.onmessage = function (e) {
+        content.document.getElementById("display").innerHTML = e.data;
+        resolve(e.data);
+      };
+    });
+
+    return result;
+  });
+
+  return response;
+}
+
+IsolationTestTools.runTests(TEST_PAGE, getResultFromSharedworker);
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/file_sharedworker.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>Page SharedWorker creator for first party isolation</title>
+</head>
+<body>
+<div id="display" style="white-space:pre; font-family:monospace; display:inline;"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/file_sharedworker.js
@@ -0,0 +1,7 @@
+self.randomValue = Math.random();
+
+onconnect = function (e) {
+  let port = e.ports[0];
+  port.postMessage(self.randomValue);
+  port.start();
+};
--- a/browser/extensions/webcompat/bootstrap.js
+++ b/browser/extensions/webcompat/bootstrap.js
@@ -1,10 +1,9 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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/. */
 
-// for now we ship a stub, that can be upgraded as-needed after release
+"use strict";
 function startup() {}
 function shutdown() {}
 function install() {}
 function uninstall() {}
--- a/browser/extensions/webcompat/moz.build
+++ b/browser/extensions/webcompat/moz.build
@@ -10,9 +10,9 @@ DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['
 FINAL_TARGET_FILES.features['webcompat@mozilla.org'] += [
   'bootstrap.js'
 ]
 
 FINAL_TARGET_PP_FILES.features['webcompat@mozilla.org'] += [
   'install.rdf.in'
 ]
 
-BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
+BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
rename from browser/extensions/webcompat/test/browser.ini
rename to browser/extensions/webcompat/test/browser/browser.ini
--- a/browser/extensions/webcompat/test/browser.ini
+++ b/browser/extensions/webcompat/test/browser/browser.ini
@@ -1,3 +1,3 @@
 [DEFAULT]
 
-[browser_webcompat_stub_check.js]
+[browser_check_installed.js]
rename from browser/extensions/webcompat/test/browser_webcompat_stub_check.js
rename to browser/extensions/webcompat/test/browser/browser_check_installed.js
--- a/browser/extensions/webcompat/test/browser_webcompat_stub_check.js
+++ b/browser/extensions/webcompat/test/browser/browser_check_installed.js
@@ -1,15 +1,13 @@
 "use strict";
 
-// make sure that the stub is present and enabled
-add_task(function* stub_enabled() {
+add_task(function* test_enabled() {
   let addon = yield new Promise(
     resolve => AddonManager.getAddonByID("webcompat@mozilla.org", resolve)
   );
-  isnot(addon, null, "Webcompat stub addon should exist");
-  is(addon.version, "1.0");
-  is(addon.name, "Web Compat");
-  ok(addon.isCompatible, "Webcompat stub addon is compatible with Firefox");
-  ok(!addon.appDisabled, "Webcompat stub addon is not app disabled");
-  ok(addon.isActive, "Webcompat stub addon is active");
-  is(addon.type, "extension", "Webcompat stub addon is type extension");
+  isnot(addon, null, "Check addon exists");
+  is(addon.version, "1.0", "Check version");
+  is(addon.name, "Web Compat", "Check name");
+  ok(addon.isCompatible, "Check application compatibility");
+  ok(!addon.appDisabled, "Check not app disabled");
+  ok(addon.isActive, "Check addon is active");
 });
deleted file mode 100644
--- a/browser/modules/PanelFrame.jsm
+++ /dev/null
@@ -1,194 +0,0 @@
-/* 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";
-
-// A module for working with panels with iframes shared across windows.
-
-this.EXPORTED_SYMBOLS = ["PanelFrame"];
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "DynamicResizeWatcher", "resource:///modules/Social.jsm");
-
-// The minimum sizes for the auto-resize panel code.
-const PANEL_MIN_HEIGHT = 100;
-const PANEL_MIN_WIDTH = 330;
-
-var PanelFrameInternal = {
-  /**
-   * Helper function to get and hold a single instance of a DynamicResizeWatcher.
-   */
-  get _dynamicResizer() {
-    delete this._dynamicResizer;
-    this._dynamicResizer = new DynamicResizeWatcher();
-    return this._dynamicResizer;
-  },
-
-  /**
-   * Status panels are one-per button per-process, we swap the docshells between
-   * windows when necessary.
-   *
-   * @param {DOMWindow} aWindow The window in which to show the popup.
-   * @param {PanelUI} aPanelUI The panel UI object that represents the application menu.
-   * @param {DOMElement} aButton The button element that is pressed to show the popup.
-   * @param {String} aType The type of panel this is, e.g. "social" or "loop".
-   * @param {String} aOrigin Optional, the origin to use for the iframe.
-   * @param {String} aSrc The url to load into the iframe.
-   * @param {String} aSize The initial size of the panel (width and height are the same
-   *                       if specified).
-   */
-  _attachNotificatonPanel: function(aWindow, aParent, aButton, aType, aOrigin, aSrc, aSize) {
-    aParent.hidden = false;
-    let notificationFrameId = aOrigin ? aType + "-status-" + aOrigin : aType + "-panel-iframe";
-    let doc = aWindow.document;
-    let frame = doc.getElementById(notificationFrameId);
-
-    // If the button was customized to a new location, destroy the
-    // iframe and start fresh.
-    if (frame && frame.parentNode != aParent) {
-      frame.parentNode.removeChild(frame);
-      frame = null;
-    }
-
-    if (!frame) {
-      let {width, height} = aSize ? aSize : {width: PANEL_MIN_WIDTH, height: PANEL_MIN_HEIGHT};
-      frame = doc.createElement("browser");
-      let attrs = {
-        "type": "content",
-        "mozbrowser": "true",
-        // All frames use social-panel-frame as the class.
-        "class": "social-panel-frame",
-        "id": notificationFrameId,
-        "tooltip": "aHTMLTooltip",
-        "context": "contentAreaContextMenu",
-        "flex": "1",
-
-        // work around bug 793057 - by making the panel roughly the final size
-        // we are more likely to have the anchor in the correct position.
-        "style": "width: " + width + "px; height: " + height + "px;",
-        "dynamicresizer": !aSize,
-
-        "origin": aOrigin,
-        "src": aSrc
-      };
-      if (aType == "social") {
-        attrs["message"] = "true";
-        attrs["messagemanagergroup"] = aType;
-      }
-      for (let [k, v] of Object.entries(attrs)) {
-        frame.setAttribute(k, v);
-      }
-      aParent.appendChild(frame);
-    } else {
-      frame.setAttribute("origin", aOrigin);
-      frame.setAttribute("src", aSrc);
-    }
-    aButton.setAttribute("notificationFrameId", notificationFrameId);
-  }
-};
-
-/**
- * The exported PanelFrame object
- */
-var PanelFrame = {
-  /**
-   * Shows a popup in a pop-up panel, or in a sliding panel view in the application menu.
-   * It will move the iframe to different DOM locations depending on where it needs to be
-   * shown, enabling one iframe to be used for the entire session.
-   *
-   * @param {DOMWindow} aWindow The window in which to show the popup.
-   * @param {PanelUI} aPanelUI The panel UI object that represents the application menu.
-   * @param {DOMElement} aToolbarButton The button element that is pressed to show the popup.
-   * @param {String} aType The type of panel this is, e.g. "social" or "loop".
-   * @param {String} aOrigin Optional, the origin to use for the iframe.
-   * @param {String} aSrc The url to load into the iframe.
-   * @param {String} aSize The initial size of the panel (width and height are the same
-   *                       if specified).
-   * @param {Function} aCallback Optional, callback to be called with the iframe when it is
-   *                             set up.
-   */
-  showPopup: function(aWindow, aToolbarButton, aType, aOrigin, aSrc, aSize, aCallback) {
-    // if we're overflowed, our anchor needs to be the overflow button
-    let widgetGroup = CustomizableUI.getWidget(aToolbarButton.getAttribute("id"));
-    let widget = widgetGroup.forWindow(aWindow);
-    // if we're a slice in the hamburger, our anchor will be the menu button,
-    // this panel will replace the menu panel when the button is clicked on
-    let anchorBtn = widget.anchor;
-
-    let panel = aWindow.document.getElementById(aType + "-notification-panel");
-    PanelFrameInternal._attachNotificatonPanel(aWindow, panel, aToolbarButton, aType, aOrigin, aSrc, aSize);
-
-    let notificationFrameId = aToolbarButton.getAttribute("notificationFrameId");
-    let notificationFrame = aWindow.document.getElementById(notificationFrameId);
-
-    // the xbl bindings for the iframe probably don't exist yet, so we can't
-    // access iframe.messageManager directly - but can get at it with this dance.
-    let mm = notificationFrame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
-
-    // Clear dimensions on all browsers so the panel size will
-    // only use the selected browser.
-    let frameIter = panel.firstElementChild;
-    while (frameIter) {
-      frameIter.collapsed = (frameIter != notificationFrame);
-      frameIter = frameIter.nextElementSibling;
-    }
-
-    function dispatchPanelEvent(name) {
-      mm.sendAsyncMessage("Social:CustomEvent", { name: name });
-    }
-
-    // we only use a dynamic resizer when we're located the toolbar.
-    let dynamicResizer;
-    if (notificationFrame.getAttribute("dynamicresizer") == "true") {
-      dynamicResizer = PanelFrameInternal._dynamicResizer;
-    }
-    panel.addEventListener("popuphidden", function onpopuphiding() {
-      panel.removeEventListener("popuphidden", onpopuphiding);
-      anchorBtn.removeAttribute("open");
-      if (dynamicResizer)
-        dynamicResizer.stop();
-      notificationFrame.docShellIsActive = false;
-      dispatchPanelEvent(aType + "FrameHide");
-    });
-
-    panel.addEventListener("popupshowing", function onpopupshowing() {
-      panel.removeEventListener("popupshowning", onpopupshowing);
-      // This attribute is needed on both the button and the
-      // containing toolbaritem since the buttons on OS X have
-      // moz-appearance:none, while their container gets
-      // moz-appearance:toolbarbutton due to the way that toolbar buttons
-      // get combined on OS X.
-      anchorBtn.setAttribute("open", "true");
-    });
-
-    panel.addEventListener("popupshown", function onpopupshown() {
-      panel.removeEventListener("popupshown", onpopupshown);
-
-      mm.sendAsyncMessage("WaitForDOMContentLoaded");
-      mm.addMessageListener("DOMContentLoaded", function onloaded() {
-        mm.removeMessageListener("DOMContentLoaded", onloaded);
-        mm = notificationFrame.messageManager;
-        notificationFrame.docShellIsActive = true;
-        if (dynamicResizer)
-          dynamicResizer.start(panel, notificationFrame);
-        dispatchPanelEvent(aType + "FrameShow");
-      });
-    });
-
-    let anchor = aWindow.document.getAnonymousElementByAttribute(anchorBtn, "class", "toolbarbutton-icon");
-    // Bug 849216 - open the popup asynchronously so we avoid the auto-rollup
-    // handling from preventing it being opened in some cases.
-    Services.tm.mainThread.dispatch(function() {
-      panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
-    }, Ci.nsIThread.DISPATCH_NORMAL);
-
-    if (aCallback)
-      aCallback(notificationFrame);
-  }
-};
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -28,17 +28,16 @@ EXTRA_JS_MODULES += [
     'E10SUtils.jsm',
     'Feeds.jsm',
     'FormSubmitObserver.jsm',
     'FormValidationHandler.jsm',
     'HiddenFrame.jsm',
     'LaterRun.jsm',
     'NetworkPrioritizer.jsm',
     'offlineAppCache.jsm',
-    'PanelFrame.jsm',
     'PermissionUI.jsm',
     'PluginContent.jsm',
     'ProcessHangMonitor.jsm',
     'ReaderParent.jsm',
     'RecentWindow.jsm',
     'RemotePrompt.jsm',
     'Sanitizer.jsm',
     'SelfSupportBackend.jsm',
deleted file mode 100644
--- a/devtools/client/.babelrc
+++ /dev/null
@@ -1,1 +0,0 @@
- { "presets": [ "es2015" ] }
\ No newline at end of file
--- a/devtools/client/inspector/rules/models/text-property.js
+++ b/devtools/client/inspector/rules/models/text-property.js
@@ -47,20 +47,21 @@ XPCOMUtils.defineLazyGetter(this, "domUt
 function TextProperty(rule, name, value, priority, enabled = true,
                       invisible = false) {
   this.rule = rule;
   this.name = name;
   this.value = value;
   this.priority = priority;
   this.enabled = !!enabled;
   this.invisible = invisible;
-  this.updateComputed();
 
   const toolbox = this.rule.elementStyle.ruleView.inspector.toolbox;
   this.cssProperties = getCssProperties(toolbox);
+
+  this.updateComputed();
 }
 
 TextProperty.prototype = {
   /**
    * Update the editor associated with this text property,
    * if any.
    */
   updateEditor: function () {
@@ -82,33 +83,28 @@ TextProperty.prototype = {
     // and see what the computed style looks like.
     let dummyElement = this.rule.elementStyle.ruleView.dummyElement;
     let dummyStyle = dummyElement.style;
     dummyStyle.cssText = "";
     dummyStyle.setProperty(this.name, this.value, this.priority);
 
     this.computed = [];
 
-    try {
-      // Manually get all the properties that are set when setting a value on
-      // this.name and check the computed style on dummyElement for each one.
-      // If we just read dummyStyle, it would skip properties when value === "".
-      let subProps = domUtils.getSubpropertiesForCSSProperty(this.name);
+    // Manually get all the properties that are set when setting a value on
+    // this.name and check the computed style on dummyElement for each one.
+    // If we just read dummyStyle, it would skip properties when value === "".
+    let subProps = this.cssProperties.getSubproperties(this.name);
 
-      for (let prop of subProps) {
-        this.computed.push({
-          textProp: this,
-          name: prop,
-          value: dummyStyle.getPropertyValue(prop),
-          priority: dummyStyle.getPropertyPriority(prop),
-        });
-      }
-    } catch (e) {
-      // This is a partial property name, probably from cutting and pasting
-      // text. At this point don't check for computed properties.
+    for (let prop of subProps) {
+      this.computed.push({
+        textProp: this,
+        name: prop,
+        value: dummyStyle.getPropertyValue(prop),
+        priority: dummyStyle.getPropertyPriority(prop),
+      });
     }
   },
 
   /**
    * Set all the values from another TextProperty instance into
    * this TextProperty instance.
    *
    * @param {TextProperty} prop
--- a/devtools/client/inspector/rules/rules.js
+++ b/devtools/client/inspector/rules/rules.js
@@ -3,17 +3,16 @@
 /* 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/. */
 /* globals gDevTools */
 
 "use strict";
 
 const promise = require("promise");
-const defer = require("devtools/shared/defer");
 const Services = require("Services");
 const {Task} = require("devtools/shared/task");
 const {Tools} = require("devtools/client/definitions");
 const {l10n} = require("devtools/shared/inspector/css-logic");
 const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
 const {OutputParser} = require("devtools/client/shared/output-parser");
 const {PrefObserver, PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
 const {ElementStyle} = require("devtools/client/inspector/rules/models/element-style");
@@ -74,57 +73,16 @@ const FILTER_STRICT_RE = /\s*`(.*?)`\s*$
  * TextPropertyEditor:
  *   Owns a TextProperty object.
  *   Manages changes to the TextProperty.
  *   Can be expanded to display computed properties.
  *   Can mark a property disabled or enabled.
  */
 
 /**
- * To figure out how shorthand properties are interpreted by the
- * engine, we will set properties on a dummy element and observe
- * how their .style attribute reflects them as computed values.
- * This function creates the document in which those dummy elements
- * will be created.
- */
-var gDummyPromise;
-function createDummyDocument() {
-  if (gDummyPromise) {
-    return gDummyPromise;
-  }
-  const { getDocShell, create: makeFrame } = require("sdk/frame/utils");
-
-  let frame = makeFrame(Services.appShell.hiddenDOMWindow.document, {
-    nodeName: "iframe",
-    namespaceURI: "http://www.w3.org/1999/xhtml",
-    allowJavascript: false,
-    allowPlugins: false,
-    allowAuth: false
-  });
-  let docShell = getDocShell(frame);
-  let eventTarget = docShell.chromeEventHandler;
-  let ssm = Services.scriptSecurityManager;
-
-  // We probably need to call InheritFromDocShellToDoc to get the correct origin
-  // attributes, but right now we can't call it from JS.
-  let nullPrincipal = ssm.createNullPrincipal(docShell.getOriginAttributes());
-  docShell.createAboutBlankContentViewer(nullPrincipal);
-  let window = docShell.contentViewer.DOMDocument.defaultView;
-  window.location = "data:text/html,<html></html>";
-  let deferred = defer();
-  eventTarget.addEventListener("DOMContentLoaded", function handler() {
-    eventTarget.removeEventListener("DOMContentLoaded", handler, false);
-    deferred.resolve(window.document);
-    frame.remove();
-  }, false);
-  gDummyPromise = deferred.promise;
-  return gDummyPromise;
-}
-
-/**
  * CssRuleView is a view of the style rules and declarations that
  * apply to a given element.  After construction, the 'element'
  * property will be available with the user interface.
  *
  * @param {Inspector} inspector
  *        Inspector toolbox panel
  * @param {Document} document
  *        The document that will contain the rule view.
@@ -712,18 +670,16 @@ CssRuleView.prototype = {
     return false;
   },
 
   destroy: function () {
     this.isDestroyed = true;
     this.clear();
 
     this._dummyElement = null;
-    this.dummyElementPromise = null;
-    gDummyPromise = null;
 
     this._prefObserver.off(PREF_ORIG_SOURCES, this._onSourcePrefChanged);
     this._prefObserver.off(PREF_UA_STYLES, this._handlePrefChange);
     this._prefObserver.off(PREF_DEFAULT_COLOR_UNIT, this._handlePrefChange);
     this._prefObserver.destroy();
 
     this._outputParser = null;
 
@@ -820,33 +776,31 @@ CssRuleView.prototype = {
       this._showEmpty();
       this.refreshPseudoClassPanel();
       return promise.resolve(undefined);
     }
 
     // To figure out how shorthand properties are interpreted by the
     // engine, we will set properties on a dummy element and observe
     // how their .style attribute reflects them as computed values.
-    this.dummyElementPromise = createDummyDocument().then(document => {
+    let dummyElementPromise = promise.resolve(this.styleDocument).then(document => {
       // ::before and ::after do not have a namespaceURI
       let namespaceURI = this.element.namespaceURI ||
           document.documentElement.namespaceURI;
       this._dummyElement = document.createElementNS(namespaceURI,
                                                    this.element.tagName);
-      document.documentElement.appendChild(this._dummyElement);
-      return this._dummyElement;
     }).then(null, promiseWarn);
 
     let elementStyle = new ElementStyle(element, this, this.store,
       this.pageStyle, this.showUserAgentStyles);
     this._elementStyle = elementStyle;
 
     this._startSelectingElement();
 
-    return this.dummyElementPromise.then(() => {
+    return dummyElementPromise.then(() => {
       if (this._elementStyle === elementStyle) {
         return this._populate();
       }
       return undefined;
     }).then(() => {
       if (this._elementStyle === elementStyle) {
         if (!refresh) {
           this.element.scrollTop = 0;
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -25,16 +25,17 @@ devtools.jar:
     content/shared/frame-script-utils.js (shared/frame-script-utils.js)
     content/styleeditor/styleeditor.xul (styleeditor/styleeditor.xul)
     content/storage/storage.xul (storage/storage.xul)
     content/inspector/fonts/fonts.js (inspector/fonts/fonts.js)
     content/inspector/markup/markup.xhtml (inspector/markup/markup.xhtml)
     content/animationinspector/animation-controller.js (animationinspector/animation-controller.js)
     content/animationinspector/animation-panel.js (animationinspector/animation-panel.js)
     content/animationinspector/animation-inspector.xhtml (animationinspector/animation-inspector.xhtml)
+    content/sourceeditor/codemirror/addon/dialog/dialog.css (sourceeditor/codemirror/addon/dialog/dialog.css)
     content/sourceeditor/codemirror/addon/hint/show-hint.js (sourceeditor/codemirror/addon/hint/show-hint.js)
     content/sourceeditor/codemirror/addon/tern/tern.js (sourceeditor/codemirror/addon/tern/tern.js)
     content/sourceeditor/codemirror/codemirror.bundle.js (sourceeditor/codemirror/codemirror.bundle.js)
     content/sourceeditor/codemirror/lib/codemirror.css (sourceeditor/codemirror/lib/codemirror.css)
     content/sourceeditor/codemirror/mozilla.css (sourceeditor/codemirror/mozilla.css)
     content/debugger/new/index.html (debugger/new/index.html)
     content/debugger/new/images/angle-brackets.svg (debugger/new/images/angle-brackets.svg)
     content/debugger/new/images/arrow.svg (debugger/new/images/arrow.svg)
--- a/devtools/client/package.json
+++ b/devtools/client/package.json
@@ -1,16 +1,19 @@
 {
   "name": "devtools",
   "version": "0.0.1",
   "description": "",
   "main": "",
   "scripts": {
     "build": "webpack"
   },
+  "babel":  {
+    "presets": [ "es2015" ]
+  },
   "author": "",
   "license": "",
   "devDependencies": {
     "babel-core": "^6.11.4",
     "babel-loader": "^6.2.4",
     "babel-preset-es2015": "^6.9.0",
     "raw-loader": "^0.5.1",
     "webpack": "^1.13.1"
--- a/devtools/client/shared/components/notification-box.css
+++ b/devtools/client/shared/components/notification-box.css
@@ -73,17 +73,17 @@
 /* Close button */
 
 .notificationbox .messageCloseButton {
   width: 20px;
   height: 20px;
   margin: 4px;
   margin-inline-end: 8px;
   background-image: url("chrome://devtools/skin/images/close.svg");
-  background-position: 3.45px 2.5px;
+  background-position: center;
   background-color: transparent;
   background-repeat: no-repeat;
   border-radius: 11px;
   filter: invert(0);
 }
 
 .notificationbox .messageCloseButton:hover {
   background-color: gray;
--- a/devtools/client/shared/test/unit/test_cssColor.js
+++ b/devtools/client/shared/test/unit/test_cssColor.js
@@ -57,9 +57,20 @@ function run_test() {
 
     // Check that our implementation matches DOMUtils.
     compareWithDomutils(test.input, true);
 
     // And check some obvious errors.
     compareWithDomutils("mumble" + test.input, false);
     compareWithDomutils(test.input + "trailingstuff", false);
   }
+
+  // Regression test for bug 1303826.
+  let black = new colorUtils.CssColor("#000");
+  black.colorUnit = "name";
+  equal(black.toString(), "black", "test non-upper-case color cycling");
+
+  let upper = new colorUtils.CssColor("BLACK");
+  upper.colorUnit = "hex";
+  equal(upper.toString(), "#000", "test upper-case color cycling");
+  upper.colorUnit = "name";
+  equal(upper.toString(), "BLACK", "test upper-case color preservation");
 }
--- a/devtools/client/storage/storage.xul
+++ b/devtools/client/storage/storage.xul
@@ -21,17 +21,17 @@
   <script type="text/javascript" src="chrome://global/content/globalOverlay.js"/>
 
   <commandset id="editMenuCommands"/>
 
   <popupset id="storagePopupSet">
     <menupopup id="storage-tree-popup">
       <menuitem id="storage-tree-popup-delete-all"
                 label="&storage.popupMenu.deleteAllLabel;"/>
-      <menuitem id="storage-tree-popup-delete-database"/>
+      <menuitem id="storage-tree-popup-delete"/>
     </menupopup>
     <menupopup id="storage-table-popup">
       <menuitem id="storage-table-popup-delete"/>
       <menuitem id="storage-table-popup-delete-all-from"/>
       <menuitem id="storage-table-popup-delete-all"
                 label="&storage.popupMenu.deleteAllLabel;"/>
     </menupopup>
   </popupset>
--- a/devtools/client/storage/test/browser.ini
+++ b/devtools/client/storage/test/browser.ini
@@ -14,16 +14,17 @@ support-files =
   storage-secured-iframe.html
   storage-sessionstorage.html
   storage-unsecured-iframe.html
   storage-updates.html
   head.js
   !/devtools/client/framework/test/shared-head.js
 
 [browser_storage_basic.js]
+[browser_storage_cache_delete.js]
 [browser_storage_cache_error.js]
 [browser_storage_cookies_delete_all.js]
 [browser_storage_cookies_domain.js]
 [browser_storage_cookies_edit.js]
 [browser_storage_cookies_edit_keyboard.js]
 [browser_storage_cookies_tab_navigation.js]
 [browser_storage_delete.js]
 [browser_storage_delete_all.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/storage/test/browser_storage_cache_delete.js
@@ -0,0 +1,46 @@
+/* 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/. */
+
+/* import-globals-from ../../framework/test/shared-head.js */
+
+"use strict";
+
+// Test deleting a Cache object from the tree using context menu
+
+add_task(function* () {
+  yield openTabAndSetupStorage(MAIN_DOMAIN + "storage-listings.html");
+
+  let contextMenu = gPanelWindow.document.getElementById("storage-tree-popup");
+  let menuDeleteItem = contextMenu.querySelector("#storage-tree-popup-delete");
+
+  let cacheToDelete = ["Cache", "http://test1.example.org", "plop"];
+
+  info("test state before delete");
+  yield selectTreeItem(cacheToDelete);
+  ok(gUI.tree.isSelected(cacheToDelete), "Cache item is present in the tree");
+
+  info("do the delete");
+  let eventWait = gUI.once("store-objects-updated");
+
+  let selector = `[data-id='${JSON.stringify(cacheToDelete)}'] > .tree-widget-item`;
+  let target = gPanelWindow.document.querySelector(selector);
+  ok(target, "Cache item's tree element is present");
+
+  yield waitForContextMenu(contextMenu, target, () => {
+    info("Opened tree context menu");
+    menuDeleteItem.click();
+
+    let cacheName = cacheToDelete[2];
+    ok(menuDeleteItem.getAttribute("label").includes(cacheName),
+      `Context menu item label contains '${cacheName}')`);
+  });
+
+  yield eventWait;
+
+  info("test state after delete");
+  yield selectTreeItem(cacheToDelete);
+  ok(!gUI.tree.isSelected(cacheToDelete), "Cache item is no longer present in the tree");
+
+  yield finishTests();
+});
--- a/devtools/client/storage/test/browser_storage_delete.js
+++ b/devtools/client/storage/test/browser_storage_delete.js
@@ -11,17 +11,19 @@
 const TEST_CASES = [
   [["localStorage", "http://test1.example.org"],
     "ls1", "name"],
   [["sessionStorage", "http://test1.example.org"],
     "ss1", "name"],
   [["cookies", "test1.example.org"],
     "c1", "name"],
   [["indexedDB", "http://test1.example.org", "idb1", "obj1"],
-    1, "name"]
+    1, "name"],
+  [["Cache", "http://test1.example.org", "plop"],
+    MAIN_DOMAIN + "404_cached_file.js", "url"],
 ];
 
 add_task(function* () {
   yield openTabAndSetupStorage(MAIN_DOMAIN + "storage-listings.html");
 
   let contextMenu = gPanelWindow.document.getElementById("storage-table-popup");
   let menuDeleteItem = contextMenu.querySelector("#storage-table-popup-delete");
 
@@ -34,18 +36,19 @@ add_task(function* () {
     let row = getRowCells(rowName);
     ok(gUI.table.items.has(rowName), `There is a row '${rowName}' in ${treeItemName}`);
 
     let eventWait = gUI.once("store-objects-updated");
 
     yield waitForContextMenu(contextMenu, row[cellToClick], () => {
       info(`Opened context menu in ${treeItemName}, row '${rowName}'`);
       menuDeleteItem.click();
-      ok(menuDeleteItem.getAttribute("label").includes(rowName),
-        `Context menu item label contains '${rowName}'`);
+      let truncatedRowName = String(rowName).substr(0, 16);
+      ok(menuDeleteItem.getAttribute("label").includes(truncatedRowName),
+        `Context menu item label contains '${rowName}' (maybe truncated)`);
     });
 
     yield eventWait;
 
     ok(!gUI.table.items.has(rowName),
       `There is no row '${rowName}' in ${treeItemName} after deletion`);
   }
 
--- a/devtools/client/storage/test/browser_storage_delete_all.js
+++ b/devtools/client/storage/test/browser_storage_delete_all.js
@@ -26,35 +26,39 @@ add_task(function* () {
     [["sessionStorage", "http://test1.example.org"],
       ["ss1"]],
     [["sessionStorage", "http://sectest1.example.org"],
       ["iframe-u-ss1", "iframe-u-ss2"]],
     [["sessionStorage", "https://sectest1.example.org"],
       ["iframe-s-ss1"]],
     [["indexedDB", "http://test1.example.org", "idb1", "obj1"],
       [1, 2, 3]],
+    [["Cache", "http://test1.example.org", "plop"],
+      [MAIN_DOMAIN + "404_cached_file.js", MAIN_DOMAIN + "browser_storage_basic.js"]],
   ];
 
   yield checkState(beforeState);
 
   info("do the delete");
   const deleteHosts = [
-    [["localStorage", "https://sectest1.example.org"], "iframe-s-ls1"],
-    [["sessionStorage", "https://sectest1.example.org"], "iframe-s-ss1"],
-    [["indexedDB", "http://test1.example.org", "idb1", "obj1"], 1],
+    [["localStorage", "https://sectest1.example.org"], "iframe-s-ls1", "name"],
+    [["sessionStorage", "https://sectest1.example.org"], "iframe-s-ss1", "name"],
+    [["indexedDB", "http://test1.example.org", "idb1", "obj1"], 1, "name"],
+    [["Cache", "http://test1.example.org", "plop"],
+      MAIN_DOMAIN + "404_cached_file.js", "url"],
   ];
 
-  for (let [store, rowName] of deleteHosts) {
+  for (let [store, rowName, cellToClick] of deleteHosts) {
     let storeName = store.join(" > ");
 
     yield selectTreeItem(store);
 
     let eventWait = gUI.once("store-objects-cleared");
 
-    let cell = getRowCells(rowName).name;
+    let cell = getRowCells(rowName)[cellToClick];
     yield waitForContextMenu(contextMenu, cell, () => {
       info(`Opened context menu in ${storeName}, row '${rowName}'`);
       menuDeleteAllItem.click();
     });
 
     yield eventWait;
   }
 
@@ -71,14 +75,16 @@ add_task(function* () {
     [["sessionStorage", "http://test1.example.org"],
       ["ss1"]],
     [["sessionStorage", "http://sectest1.example.org"],
       ["iframe-u-ss1", "iframe-u-ss2"]],
     [["sessionStorage", "https://sectest1.example.org"],
       []],
     [["indexedDB", "http://test1.example.org", "idb1", "obj1"],
       []],
+    [["Cache", "http://test1.example.org", "plop"],
+      []],
   ];
 
   yield checkState(afterState);
 
   yield finishTests();
 });
--- a/devtools/client/storage/test/browser_storage_delete_tree.js
+++ b/devtools/client/storage/test/browser_storage_delete_tree.js
@@ -16,24 +16,27 @@ add_task(function* () {
     "#storage-tree-popup-delete-all");
 
   info("test state before delete");
   yield checkState([
     [["cookies", "test1.example.org"], ["c1", "c3", "cs2", "uc1"]],
     [["localStorage", "http://test1.example.org"], ["ls1", "ls2"]],
     [["sessionStorage", "http://test1.example.org"], ["ss1"]],
     [["indexedDB", "http://test1.example.org", "idb1", "obj1"], [1, 2, 3]],
+    [["Cache", "http://test1.example.org", "plop"],
+      [MAIN_DOMAIN + "404_cached_file.js", MAIN_DOMAIN + "browser_storage_basic.js"]],
   ]);
 
   info("do the delete");
   const deleteHosts = [
     ["cookies", "test1.example.org"],
     ["localStorage", "http://test1.example.org"],
     ["sessionStorage", "http://test1.example.org"],
     ["indexedDB", "http://test1.example.org", "idb1", "obj1"],
+    ["Cache", "http://test1.example.org", "plop"],
   ];
 
   for (let store of deleteHosts) {
     let storeName = store.join(" > ");
 
     yield selectTreeItem(store);
 
     let eventName = "store-objects-" +
@@ -52,12 +55,13 @@ add_task(function* () {
   }
 
   info("test state after delete");
   yield checkState([
     [["cookies", "test1.example.org"], []],
     [["localStorage", "http://test1.example.org"], []],
     [["sessionStorage", "http://test1.example.org"], []],
     [["indexedDB", "http://test1.example.org", "idb1", "obj1"], []],
+    [["Cache", "http://test1.example.org", "plop"], []],
   ]);
 
   yield finishTests();
 });
--- a/devtools/client/storage/test/browser_storage_indexeddb_delete.js
+++ b/devtools/client/storage/test/browser_storage_indexeddb_delete.js
@@ -7,18 +7,17 @@
 "use strict";
 
 // Test deleting indexedDB database from the tree using context menu
 
 add_task(function* () {
   yield openTabAndSetupStorage(MAIN_DOMAIN + "storage-empty-objectstores.html");
 
   let contextMenu = gPanelWindow.document.getElementById("storage-tree-popup");
-  let menuDeleteDb = contextMenu.querySelector(
-    "#storage-tree-popup-delete-database");
+  let menuDeleteDb = contextMenu.querySelector("#storage-tree-popup-delete");
 
   info("test state before delete");
   yield checkState([
     [["indexedDB", "http://test1.example.org"], ["idb1", "idb2"]],
   ]);
 
   info("do the delete");
   const deletedDb = ["indexedDB", "http://test1.example.org", "idb1"];
--- a/devtools/client/storage/ui.js
+++ b/devtools/client/storage/ui.js
@@ -62,16 +62,23 @@ const COOKIE_KEY_MAP = {
 };
 
 // Maximum length of item name to show in context menu label - will be
 // trimmed with ellipsis if it's longer.
 const ITEM_NAME_MAX_LENGTH = 32;
 
 function addEllipsis(name) {
   if (name.length > ITEM_NAME_MAX_LENGTH) {
+    if (/^https?:/.test(name)) {
+      // For URLs, add ellipsis in the middle
+      const halfLen = ITEM_NAME_MAX_LENGTH / 2;
+      return name.slice(0, halfLen) + ELLIPSIS + name.slice(-halfLen);
+    }
+
+    // For other strings, add ellipsis at the end
     return name.substr(0, ITEM_NAME_MAX_LENGTH) + ELLIPSIS;
   }
 
   return name;
 }
 
 /**
  * StorageUI is controls and builds the UI of the Storage Inspector.
@@ -152,17 +159,17 @@ function StorageUI(front, target, panelW
 
   this.onTablePopupShowing = this.onTablePopupShowing.bind(this);
   this._tablePopup = this._panelDoc.getElementById("storage-table-popup");
   this._tablePopup.addEventListener("popupshowing", this.onTablePopupShowing);
 
   this.onRemoveItem = this.onRemoveItem.bind(this);
   this.onRemoveAllFrom = this.onRemoveAllFrom.bind(this);
   this.onRemoveAll = this.onRemoveAll.bind(this);
-  this.onRemoveDatabase = this.onRemoveDatabase.bind(this);
+  this.onRemoveTreeItem = this.onRemoveTreeItem.bind(this);
 
   this._tablePopupDelete = this._panelDoc.getElementById(
     "storage-table-popup-delete");
   this._tablePopupDelete.addEventListener("command", this.onRemoveItem);
 
   this._tablePopupDeleteAllFrom = this._panelDoc.getElementById(
     "storage-table-popup-delete-all-from");
   this._tablePopupDeleteAllFrom.addEventListener("command",
@@ -171,20 +178,18 @@ function StorageUI(front, target, panelW
   this._tablePopupDeleteAll = this._panelDoc.getElementById(
     "storage-table-popup-delete-all");
   this._tablePopupDeleteAll.addEventListener("command", this.onRemoveAll);
 
   this._treePopupDeleteAll = this._panelDoc.getElementById(
     "storage-tree-popup-delete-all");
   this._treePopupDeleteAll.addEventListener("command", this.onRemoveAll);
 
-  this._treePopupDeleteDatabase = this._panelDoc.getElementById(
-    "storage-tree-popup-delete-database");
-  this._treePopupDeleteDatabase.addEventListener("command",
-    this.onRemoveDatabase);
+  this._treePopupDelete = this._panelDoc.getElementById("storage-tree-popup-delete");
+  this._treePopupDelete.addEventListener("command", this.onRemoveTreeItem);
 }
 
 exports.StorageUI = StorageUI;
 
 StorageUI.prototype = {
 
   storageTypes: null,
   shouldLoadMoreItems: true,
@@ -200,31 +205,24 @@ StorageUI.prototype = {
     this.table.destroy();
 
     this.front.off("stores-update", this.onUpdate);
     this.front.off("stores-cleared", this.onCleared);
     this._panelDoc.removeEventListener("keypress", this.handleKeypress);
     this.searchBox.removeEventListener("input", this.filterItems);
     this.searchBox = null;
 
-    this._treePopup.removeEventListener("popupshowing",
-      this.onTreePopupShowing);
-    this._treePopupDeleteAll.removeEventListener("command",
-      this.onRemoveAll);
-    this._treePopupDeleteDatabase.removeEventListener("command",
-      this.onRemoveDatabase);
+    this._treePopup.removeEventListener("popupshowing", this.onTreePopupShowing);
+    this._treePopupDeleteAll.removeEventListener("command", this.onRemoveAll);
+    this._treePopupDelete.removeEventListener("command", this.onRemoveTreeItem);
 
-    this._tablePopup.removeEventListener("popupshowing",
-      this.onTablePopupShowing);
-    this._tablePopupDelete.removeEventListener("command",
-      this.onRemoveItem);
-    this._tablePopupDeleteAllFrom.removeEventListener("command",
-      this.onRemoveAllFrom);
-    this._tablePopupDeleteAll.removeEventListener("command",
-      this.onRemoveAll);
+    this._tablePopup.removeEventListener("popupshowing", this.onTablePopupShowing);
+    this._tablePopupDelete.removeEventListener("command", this.onRemoveItem);
+    this._tablePopupDeleteAllFrom.removeEventListener("command", this.onRemoveAllFrom);
+    this._tablePopupDeleteAll.removeEventListener("command", this.onRemoveAll);
   },
 
   /**
    * Empties and hides the object viewer sidebar
    */
   hideSidebar: function () {
     this.view.empty();
     this.sidebar.hidden = true;
@@ -939,34 +937,49 @@ StorageUI.prototype = {
     let showMenu = false;
     let selectedItem = this.tree.selectedItem;
 
     if (selectedItem) {
       let type = selectedItem[0];
       let actor = this.storageTypes[type];
 
       // The delete all (aka clear) action is displayed for IndexedDB object stores
-      // (level 4 of tree) and for the whole host (level 2 of tree) of other storage
-      // types (cookies, localStorage, ...).
-      let showDeleteAll = actor.removeAll &&
-        (selectedItem.length === (type === "indexedDB" ? 4 : 2));
+      // (level 4 of tree), for Cache objects (level 3) and for the whole host (level 2)
+      // for other storage types (cookies, localStorage, ...).
+      let showDeleteAll = false;
+      if (actor.removeAll) {
+        let level;
+        if (type == "indexedDB") {
+          level = 4;
+        } else if (type == "Cache") {
+          level = 3;
+        } else {
+          level = 2;
+        }
+
+        if (selectedItem.length == level) {
+          showDeleteAll = true;
+        }
+      }
 
       this._treePopupDeleteAll.hidden = !showDeleteAll;
 
-      // The action to delete database is available for IndexedDB databases, i.e.,
-      // at level 3 of the tree.
-      let showDeleteDb = actor.removeDatabase && selectedItem.length === 3;
-      this._treePopupDeleteDatabase.hidden = !showDeleteDb;
-      if (showDeleteDb) {
-        let dbName = addEllipsis(selectedItem[2]);
-        this._treePopupDeleteDatabase.setAttribute("label",
-          L10N.getFormatStr("storage.popupMenu.deleteLabel", dbName));
+      // The delete action is displayed for:
+      // - IndexedDB databases (level 3 of the tree)
+      // - Cache objects (level 3 of the tree)
+      let showDelete = (type == "indexedDB" || type == "Cache") &&
+                       selectedItem.length == 3;
+      this._treePopupDelete.hidden = !showDelete;
+      if (showDelete) {
+        let itemName = addEllipsis(selectedItem[selectedItem.length - 1]);
+        this._treePopupDelete.setAttribute("label",
+          L10N.getFormatStr("storage.popupMenu.deleteLabel", itemName));
       }
 
-      showMenu = showDeleteAll || showDeleteDb;
+      showMenu = showDeleteAll || showDelete;
     }
 
     if (!showMenu) {
       event.preventDefault();
     }
   },
 
   /**
@@ -1005,31 +1018,46 @@ StorageUI.prototype = {
     let [, host] = this.tree.selectedItem;
     let actor = this.getCurrentActor();
     let rowId = this.table.contextMenuRowId;
     let data = this.table.items.get(rowId);
 
     actor.removeAll(host, data.host);
   },
 
-  onRemoveDatabase: function () {
-    let [type, host, name] = this.tree.selectedItem;
-    let actor = this.storageTypes[type];
+  onRemoveTreeItem: function () {
+    let [type, host, ...path] = this.tree.selectedItem;
 
-    actor.removeDatabase(host, name).then(result => {
+    if (type == "indexedDB" && path.length == 1) {
+      this.removeDatabase(host, path[0]);
+    } else if (type == "Cache" && path.length == 1) {
+      this.removeCache(host, path[0]);
+    }
+  },
+
+  removeDatabase: function (host, dbName) {
+    let actor = this.storageTypes.indexedDB;
+
+    actor.removeDatabase(host, dbName).then(result => {
       if (result.blocked) {
         let notificationBox = this._toolbox.getNotificationBox();
         notificationBox.appendNotification(
-          L10N.getFormatStr("storage.idb.deleteBlocked", name),
+          L10N.getFormatStr("storage.idb.deleteBlocked", dbName),
           "storage-idb-delete-blocked",
           null,
           notificationBox.PRIORITY_WARNING_LOW);
       }
     }).catch(error => {
       let notificationBox = this._toolbox.getNotificationBox();
       notificationBox.appendNotification(
-        L10N.getFormatStr("storage.idb.deleteError", name),
+        L10N.getFormatStr("storage.idb.deleteError", dbName),
         "storage-idb-delete-error",
         null,
         notificationBox.PRIORITY_CRITICAL_LOW);
     });
-  }
+  },
+
+  removeCache: function (host, cacheName) {
+    let actor = this.storageTypes.Cache;
+
+    actor.removeItem(host, JSON.stringify([ cacheName ]));
+  },
 };
--- a/devtools/client/themes/images/close.svg
+++ b/devtools/client/themes/images/close.svg
@@ -1,6 +1,6 @@
 <!-- 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/. -->
-<svg width="17" height="17" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill="#0b0b0b">
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#0b0b0b">
   <path d="M8.707 8l4.23 4.23a.5.5 0 1 1-.707.707L8 8.707l-4.23 4.23a.5.5 0 1 1-.707-.707L7.293 8l-4.23-4.23a.5.5 0 1 1 .707-.707L8 7.293l4.23-4.23a.5.5 0 0 1 .707.707L8.707 8z" fill-rule="evenodd"/>
 </svg>
--- a/devtools/client/themes/responsivedesign.inc.css
+++ b/devtools/client/themes/responsivedesign.inc.css
@@ -164,18 +164,16 @@
 }
 
 .devtools-responsiveui-close {
   list-style-image: url("chrome://devtools/skin/images/close.svg");
 }
 
 .devtools-responsiveui-close > image {
   filter: invert(1);
-  padding-inline-start: 3px;
-  padding-top: 2px;
 }
 
 .devtools-responsiveui-rotate {
   list-style-image: url("chrome://devtools/skin/images/responsivemode/responsiveui-rotate.png");
 }
 
 @media (min-resolution: 1.1dppx) {
   .devtools-responsiveui-rotate {
--- a/devtools/server/actors/css-properties.js
+++ b/devtools/server/actors/css-properties.js
@@ -70,24 +70,27 @@ function generateCssProperties() {
 
     // Don't send colors over RDP, these will be re-attached by the front.
     let values = DOMUtils.getCSSValuesForProperty(name);
     if (values.includes("aliceblue")) {
       values = values.filter(x => !colors.includes(x));
       values.unshift("COLOR");
     }
 
+    let subproperties = DOMUtils.getSubpropertiesForCSSProperty(name);
+
     // In order to maintain any backwards compatible changes when debugging older
     // clients, take the definition from the static CSS properties database, and fill it
     // in with the most recent property definition from the server.
     const clientDefinition = CSS_PROPERTIES[name] || {};
     const serverDefinition = {
       isInherited: DOMUtils.isInheritedProperty(name),
       values,
-      supports
+      supports,
+      subproperties,
     };
     properties[name] = Object.assign(clientDefinition, serverDefinition);
   });
 
   return properties;
 }
 exports.generateCssProperties = generateCssProperties;
 
--- a/devtools/server/actors/storage.js
+++ b/devtools/server/actors/storage.js
@@ -1245,16 +1245,71 @@ StorageActors.createActor({
   getSchemaAndHost(url) {
     let uri = Services.io.newURI(url, null, null);
     return uri.scheme + "://" + uri.hostPort;
   },
 
   toStoreObject(item) {
     return item;
   },
+
+  removeItem: Task.async(function* (host, name) {
+    const cacheMap = this.hostVsStores.get(host);
+    if (!cacheMap) {
+      return;
+    }
+
+    const parsedName = JSON.parse(name);
+
+    if (parsedName.length == 1) {
+      // Delete the whole Cache object
+      const [ cacheName ] = parsedName;
+      cacheMap.delete(cacheName);
+      const cacheStorage = yield this.getCachesForHost(host);
+      yield cacheStorage.delete(cacheName);
+      this.onItemUpdated("deleted", host, [ cacheName ]);
+    } else if (parsedName.length == 2) {
+      // Delete one cached request
+      const [ cacheName, url ] = parsedName;
+      const cache = cacheMap.get(cacheName);
+      if (cache) {
+        yield cache.delete(url);
+        this.onItemUpdated("deleted", host, [ cacheName, url ]);
+      }
+    }
+  }),
+
+  removeAll: Task.async(function* (host, name) {
+    const cacheMap = this.hostVsStores.get(host);
+    if (!cacheMap) {
+      return;
+    }
+
+    const parsedName = JSON.parse(name);
+
+    // Only a Cache object is a valid object to clear
+    if (parsedName.length == 1) {
+      const [ cacheName ] = parsedName;
+      const cache = cacheMap.get(cacheName);
+      if (cache) {
+        let keys = yield cache.keys();
+        yield promise.all(keys.map(key => cache.delete(key)));
+        this.onItemUpdated("cleared", host, [ cacheName ]);
+      }
+    }
+  }),
+
+  /**
+   * CacheStorage API doesn't support any notifications, we must fake them
+   */
+  onItemUpdated(action, host, path) {
+    this.storageActor.update(action, "Cache", {
+      [host]: [ JSON.stringify(path) ]
+    });
+  },
 });
 
 /**
  * Code related to the Indexed DB actor and front
  */
 
 // Metadata holder objects for various components of Indexed DB
 
--- a/devtools/shared/css/color.js
+++ b/devtools/shared/css/color.js
@@ -84,22 +84,29 @@ CssColor.prototype = {
   _colorUnit: null,
   _colorUnitUppercase: false,
 
   // The value as-authored.
   authored: null,
   // A lower-cased copy of |authored|.
   lowerCased: null,
 
+  _setColorUnitUppercase: function (color) {
+    // Specifically exclude the case where the color is
+    // case-insensitive.  This makes it so that "#000" isn't
+    // considered "upper case" for the purposes of color cycling.
+    this._colorUnitUppercase = (color === color.toUpperCase()) &&
+      (color !== color.toLowerCase());
+  },
+
   get colorUnit() {
     if (this._colorUnit === null) {
       let defaultUnit = Services.prefs.getCharPref(COLOR_UNIT_PREF);
       this._colorUnit = CssColor.COLORUNIT[defaultUnit];
-      this._colorUnitUppercase =
-        (this.authored === this.authored.toUpperCase());
+      this._setColorUnitUppercase(this.authored);
     }
     return this._colorUnit;
   },
 
   set colorUnit(unit) {
     this._colorUnit = unit;
   },
 
@@ -109,17 +116,17 @@ CssColor.prototype = {
    * color unit untouched.
    *
    * @param {String} color The color to use
    */
   setAuthoredUnitFromColor: function (color) {
     if (Services.prefs.getCharPref(COLOR_UNIT_PREF) ===
         CssColor.COLORUNIT.authored) {
       this._colorUnit = classifyColor(color);
-      this._colorUnitUppercase = (color === color.toUpperCase());
+      this._setColorUnitUppercase(color);
     }
   },
 
   get hasAlpha() {
     if (!this.valid) {
       return false;
     }
     return this._getRGBATuple().a !== 1;
@@ -316,16 +323,17 @@ CssColor.prototype = {
    *         Any valid color string
    */
   newColor: function (color) {
     // Store a lower-cased version of the color to help with format
     // testing.  The original text is kept as well so it can be
     // returned when needed.
     this.lowerCased = color.toLowerCase();
     this.authored = color;
+    this._setColorUnitUppercase(color);
     return this;
   },
 
   nextColorUnit: function () {
     // Reorder the formats array to have the current format at the
     // front so we can cycle through.
     let formats = ["hex", "hsl", "rgb", "name"];
     let currentFormat = classifyColor(this.toString());
--- a/devtools/shared/css/generated/generate-properties-db.js
+++ b/devtools/shared/css/generated/generate-properties-db.js
@@ -11,16 +11,20 @@
 var {require} = Components.utils.import("resource://devtools/shared/Loader.jsm", {});
 var {generateCssProperties} = require("devtools/server/actors/css-properties");
 
 // Output JSON
 dump(JSON.stringify({
   cssProperties: cssProperties(),
   pseudoElements: pseudoElements()
 }));
+// In a debug build, xpcshell might print extra debugging information,
+// so we emit a trailing newline and then arrange to just read a
+// single (long) line of JSON from the output.
+dump("\n");
 
 /*
  * A list of CSS Properties and their various characteristics. This is used on the
  * client-side when the CssPropertiesActor is not found, or when the client and server
  * are the same version. A single property takes the form:
  *
  *  "animation": {
  *    "isInherited": false,
--- a/devtools/shared/css/generated/mach_commands.py
+++ b/devtools/shared/css/generated/mach_commands.py
@@ -53,17 +53,20 @@ class MachCommands(MachCommandBase):
 
         cpp = self.substs['CPP']
 
         if not cpp:
             print("Unable to find the cpp program. Please do a full, non-artifact")
             print("build and try this again.")
             sys.exit(1)
 
-        cmd = shellutil.split(cpp)
+        if type(cpp) is list:
+            cmd = cpp
+        else:
+            cmd = shellutil.split(cpp)
         cmd += shellutil.split(self.substs['ACDEFINES'])
         cmd.append(headerPath)
 
         # The preprocessed list takes the following form:
         # [ (name, prop, id, flags, pref, proptype), ... ]
         preprocessed = eval(subprocess.check_output(cmd))
 
         # Map this list
@@ -77,24 +80,34 @@ class MachCommands(MachCommandBase):
 
     def get_properties_db_from_xpcshell(self):
         """Generate the static css properties db for devtools from an xpcshell script."""
         build = MozbuildObject.from_environment()
 
         # Get the paths
         script_path = resolve_path(self.topsrcdir,
             'devtools/shared/css/generated/generate-properties-db.js')
+        gre_path = resolve_path(self.topobjdir, 'dist/bin')
         browser_path = resolve_path(self.topobjdir, 'dist/bin/browser')
         xpcshell_path = build.get_binary_path(what='xpcshell')
         print(browser_path)
 
+        sub_env = dict(os.environ)
+        if sys.platform.startswith('linux'):
+            sub_env["LD_LIBRARY_PATH"] = gre_path
+
         # Run the xcpshell script, and set the appdir flag to the browser path so that
         # we have the proper dependencies for requiring the loader.
-        contents = subprocess.check_output([xpcshell_path, '-a', browser_path,
-                                            script_path])
+        contents = subprocess.check_output([xpcshell_path, '-g', gre_path,
+                                            '-a', browser_path, script_path],
+                                           env = sub_env)
+        # Extract just the first line of output, since a debug-build
+        # xpcshell might emit extra output that we don't want.
+        contents = contents.split('\n')[0]
+
         return json.loads(contents)
 
     def output_template(self, substitutions):
         """Output a the properties-db.js from a template."""
         js_template_path = resolve_path(self.topsrcdir,
             'devtools/shared/css/generated/properties-db.js.in')
         destination_path = resolve_path(self.topsrcdir,
             'devtools/shared/css/generated/properties-db.js')
--- a/devtools/shared/css/generated/properties-db.js
+++ b/devtools/shared/css/generated/properties-db.js
@@ -11,22 +11,22 @@
  * to generate these files can be found at devtools/shared/css/generate-properties-db.js.
  */
 
 /* eslint-disable max-len */
 
 /**
  * A list of CSS Properties and their various characteristics.
  */
-exports.CSS_PROPERTIES = {"all": {"values": ["COLOR", "-moz-all", "-moz-available", "-moz-block-height", "-moz-box", "-moz-calc", "-moz-center", "-moz-crisp-edges", "-moz-deck", "-moz-element", "-moz-fit-content", "-moz-grid", "-moz-grid-group", "-moz-grid-line", "-moz-groupbox", "-moz-gtk-info-bar", "-moz-hidden-unscrollable", "-moz-image-rect", "-moz-inline-box", "-moz-inline-grid", "-moz-inline-stack", "-moz-left", "-moz-linear-gradient", "-moz-mac-disclosure-button-closed", "-moz-mac-disclosure-button-open", "-moz-mac-fullscreen-button", "-moz-mac-help-button", "-moz-mac-source-list", "-moz-mac-vibrancy-dark", "-moz-mac-vibrancy-light", "-moz-max-content", "-moz-middle-with-baseline", "-moz-min-content", "-moz-none", "-moz-popup", "-moz-pre-space", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "-moz-right", "-moz-stack", "-moz-text", "-moz-use-text-color", "-moz-win-borderless-glass", "-moz-win-browsertabbar-toolbox", "-moz-win-communications-toolbox", "-moz-win-exclude-glass", "-moz-win-glass", "-moz-win-media-toolbox", "-moz-window-button-box", "-moz-window-button-box-maximized", "-moz-window-button-close", "-moz-window-button-maximize", "-moz-window-button-minimize", "-moz-window-button-restore", "-moz-window-frame-bottom", "-moz-window-frame-left", "-moz-window-frame-right", "-moz-window-titlebar", "-moz-window-titlebar-maximized", "-webkit-box", "-webkit-flex", "-webkit-inline-box", "-webkit-inline-flex", "absolute", "active", "add", "all", "all-petite-caps", "all-small-caps", "alpha", "alphabetic", "alternate", "alternate-reverse", "always", "auto", "avoid", "backwards", "balance", "baseline", "bevel", "block", "block-axis", "border-box", "both", "bottom", "bottom-outside", "break-all", "break-word", "butt", "button", "button-arrow-down", "button-arrow-next", "button-arrow-previous", "button-arrow-up", "button-bevel", "button-focus", "calc", "capitalize", "caret", "center", "central", "checkbox", "checkbox-container", "checkbox-label", "checkmenuitem", "clone", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", "condensed", "contain", "content-box", "contents", "cover", "crispedges", "cubic-bezier", "currentColor", "darken", "dashed", "default", "dialog", "difference", "disabled", "dotted", "double", "drag", "dualbutton", "ease", "ease-in", "ease-in-out", "ease-out", "economy", "element", "elements", "enabled", "end", "evenodd", "exact", "exclude", "exclusion", "expanded", "extra-condensed", "extra-expanded", "fill", "fill-box", "fixed", "flat", "flex", "flex-end", "flex-start", "forwards", "full-width", "geometricprecision", "grayscale", "grid", "groove", "groupbox", "hanging", "hard-light", "hidden", "hide", "horizontal", "horizontal-tb", "hsl", "hsla", "hue", "ideographic", "ignore", "inactive", "infinite", "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-end", "inline-flex", "inline-grid", "inline-start", "inline-table", "inset", "inside", "intersect", "isolate", "italic", "justify", "keep-all", "large", "larger", "last-baseline", "left", "lighten", "linear", "linear-gradient", "linearrgb", "list-item", "listbox", "listitem", "local", "lowercase", "lr", "lr-tb", "luminance", "luminosity", "mandatory", "manipulation", "manual", "margin-box", "match-source", "mathematical", "medium", "menuarrow", "menubar", "menucheckbox", "menuimage", "menuitem", "menuitemtext", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menupopup", "menuradio", "menuseparator", "meterbar", "meterchunk", "middle", "miter", "mixed", "multiply", "no-change", "no-drag", "no-repeat", "non-scaling-stroke", "none", "nonzero", "normal", "nowrap", "number-input", "oblique", "optimizelegibility", "optimizequality", "optimizespeed", "outset", "outside", "over", "overlay", "padding-box", "painted", "pan-x", "pan-y", "paused", "petite-caps", "pre", "pre-line", "pre-wrap", "preserve-3d", "progressbar", "progressbar-vertical", "progresschunk", "progresschunk-vertical", "proximity", "radial-gradient", "radio", "radio-container", "radio-label", "radiomenuitem", "range", "range-thumb", "read-only", "read-write", "relative", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "reset-size", "resizer", "resizerpanel", "reverse", "rgb", "rgba", "ridge", "right", "rl", "rl-tb", "round", "row", "row-reverse", "ruby", "ruby-base", "ruby-base-container", "ruby-text", "ruby-text-container", "running", "saturation", "scale-down", "scale-horizontal", "scale-vertical", "scalethumb-horizontal", "scalethumb-vertical", "scalethumbend", "scalethumbstart", "scalethumbtick", "screen", "scroll", "scrollbar", "scrollbar-horizontal", "scrollbar-small", "scrollbar-vertical", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbarthumb-horizontal", "scrollbarthumb-vertical", "scrollbartrack-horizontal", "scrollbartrack-vertical", "searchfield", "select-after", "select-all", "select-before", "select-menu", "select-same", "self-end", "self-start", "semi-condensed", "semi-expanded", "separate", "separator", "show", "sideways", "sideways-lr", "sideways-right", "sideways-rl", "slice", "small", "small-caps", "smaller", "smooth", "soft-light", "solid", "space", "space-around", "space-between", "space-evenly", "spinner", "spinner-downbutton", "spinner-textfield", "spinner-upbutton", "splitter", "square", "srgb", "start", "static", "statusbar", "statusbarpanel", "step-end", "step-start", "steps", "sticky", "stretch", "stretch-to-fit", "stroke", "sub", "subtract", "super", "tab", "tab-scroll-arrow-back", "tab-scroll-arrow-forward", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "tabpanel", "tabpanels", "tb", "tb-rl", "text", "text-after-edge", "text-before-edge", "text-bottom", "text-top", "textfield", "textfield-multiline", "thick", "thin", "titling-caps", "toggle", "toolbar", "toolbarbutton", "toolbarbutton-dropdown", "toolbargripper", "toolbox", "tooltip", "top", "top-outside", "transparent", "treeheader", "treeheadercell", "treeheadersortarrow", "treeitem", "treeline", "treetwisty", "treetwistyopen", "treeview", "tri-state", "ultra-condensed", "ultra-expanded", "under", "unicase", "unset", "uppercase", "upright", "url", "use-script", "vertical", "vertical-lr", "vertical-rl", "view-box", "visible", "visiblefill", "visiblepainted", "visiblestroke", "wavy", "window", "wrap", "wrap-reverse", "write-only", "x-large", "x-small", "xx-large", "xx-small"], "supports": [1, 2, 4, 5, 6, 7, 8, 9, 10, 11], "isInherited": false}, "mask-image": {"supports": [4, 5, 11], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "isInherited": false}, "-webkit-animation-iteration-count": {"values": ["infinite", "inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "font-feature-settings": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "border-block-start-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "-webkit-flex-grow": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "scroll-snap-destination": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-font-language-override": {"values": ["inherit", "initial", "normal", "unset"], "supports": [], "isInherited": true}, "text-emphasis": {"values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": true}, "grid-row-gap": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "font-variant-east-asian": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "outline-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-webkit-flex-flow": {"values": ["column", "column-reverse", "inherit", "initial", "nowrap", "row", "row-reverse", "unset", "wrap", "wrap-reverse"], "supports": [], "isInherited": false}, "grid-column-gap": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-inline-start-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "scroll-snap-points-x": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "list-style-type": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "padding-inline-end": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-animation": {"values": ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset"], "supports": [7, 9, 10], "isInherited": false}, "-moz-border-start-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "page-break-before": {"values": ["always", "auto", "avoid", "inherit", "initial", "left", "right", "unset"], "supports": [], "isInherited": false}, "flood-color": {"values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "text-anchor": {"values": ["end", "inherit", "initial", "middle", "start", "unset"], "supports": [], "isInherited": true}, "-moz-box-pack": {"values": ["center", "end", "inherit", "initial", "justify", "start", "unset"], "supports": [], "isInherited": false}, "-webkit-user-select": {"values": ["-moz-all", "-moz-none", "-moz-text", "all", "auto", "element", "elements", "inherit", "initial", "none", "text", "toggle", "tri-state", "unset"], "supports": [], "isInherited": false}, "-moz-border-end-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "padding-left": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-tab-size": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": true}, "perspective": {"values": ["inherit", "initial", "none", "unset"], "supports": [6], "isInherited": false}, "max-block-size": {"values": ["-moz-calc", "calc", "inherit", "initial", "none", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-animation-play-state": {"values": ["inherit", "initial", "paused", "running", "unset"], "supports": [], "isInherited": false}, "-moz-column-fill": {"values": ["auto", "balance", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-moz-stack-sizing": {"values": ["ignore", "inherit", "initial", "stretch-to-fit", "unset"], "supports": [], "isInherited": false}, "border-image-repeat": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "font-variant-position": {"values": ["inherit", "initial", "normal", "sub", "super", "unset"], "supports": [], "isInherited": true}, "border-right-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "-moz-box-align": {"values": ["baseline", "center", "end", "inherit", "initial", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "border-left-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "flex-flow": {"values": ["column", "column-reverse", "inherit", "initial", "nowrap", "row", "row-reverse", "unset", "wrap", "wrap-reverse"], "supports": [], "isInherited": false}, "outline-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "font-variant-alternates": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "mask-mode": {"supports": [], "values": ["alpha", "inherit", "initial", "luminance", "match-source", "unset"], "isInherited": false}, "flex-grow": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-moz-font-feature-settings": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "-webkit-box-shadow": {"values": ["inherit", "initial", "unset"], "supports": [2, 6], "isInherited": false}, "max-width": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset"], "supports": [6, 8], "isInherited": false}, "border-inline-end-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "grid-column": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "image-orientation": {"values": ["inherit", "initial", "unset"], "supports": [1], "isInherited": true}, "animation-duration": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "-moz-animation-fill-mode": {"values": ["backwards", "both", "forwards", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "-moz-user-input": {"values": ["auto", "disabled", "enabled", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": true}, "-webkit-animation-delay": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "shape-rendering": {"values": ["auto", "crispedges", "geometricprecision", "inherit", "initial", "optimizespeed", "unset"], "supports": [], "isInherited": true}, "flex-shrink": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "text-rendering": {"values": ["auto", "geometricprecision", "inherit", "initial", "optimizelegibility", "optimizespeed", "unset"], "supports": [], "isInherited": true}, "align-items": {"values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "border-collapse": {"values": ["collapse", "inherit", "initial", "separate", "unset"], "supports": [], "isInherited": true}, "text-combine-upright": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "offset-block-end": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-border-start-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "marker": {"values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": true}, "-webkit-mask-position-y": {"supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "outline-style": {"values": ["auto", "dashed", "dotted", "double", "groove", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "color-interpolation-filters": {"values": ["auto", "inherit", "initial", "linearrgb", "srgb", "unset"], "supports": [], "isInherited": true}, "-moz-padding-end": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "font-stretch": {"values": ["condensed", "expanded", "extra-condensed", "extra-expanded", "inherit", "initial", "normal", "semi-condensed", "semi-expanded", "ultra-condensed", "ultra-expanded", "unset"], "supports": [], "isInherited": true}, "-moz-orient": {"values": ["block", "horizontal", "inherit", "initial", "inline", "unset", "vertical"], "supports": [], "isInherited": false}, "font-variant": {"values": ["all-petite-caps", "all-small-caps", "inherit", "initial", "normal", "petite-caps", "small-caps", "sub", "super", "titling-caps", "unicase", "unset"], "supports": [], "isInherited": true}, "-webkit-animation-fill-mode": {"values": ["backwards", "both", "forwards", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "-moz-animation-duration": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "border-left": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "visibility": {"values": ["collapse", "hidden", "inherit", "initial", "unset", "visible"], "supports": [], "isInherited": true}, "-moz-user-focus": {"values": ["ignore", "inherit", "initial", "none", "normal", "select-after", "select-all", "select-before", "select-menu", "select-same", "unset"], "supports": [], "isInherited": true}, "transform-box": {"values": ["border-box", "fill-box", "inherit", "initial", "unset", "view-box"], "supports": [], "isInherited": false}, "font-variant-caps": {"values": ["all-petite-caps", "all-small-caps", "inherit", "initial", "normal", "petite-caps", "small-caps", "titling-caps", "unicase", "unset"], "supports": [], "isInherited": true}, "resize": {"values": ["both", "horizontal", "inherit", "initial", "none", "unset", "vertical"], "supports": [], "isInherited": false}, "offset-inline-end": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "paint-order": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "stroke-linecap": {"values": ["butt", "inherit", "initial", "round", "square", "unset"], "supports": [], "isInherited": true}, "animation-direction": {"values": ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset"], "supports": [], "isInherited": false}, "border-top-left-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-box-align": {"values": ["baseline", "center", "end", "inherit", "initial", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "-moz-text-size-adjust": {"values": ["auto", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": true}, "list-style": {"values": ["inherit", "initial", "inside", "none", "outside", "unset", "url"], "supports": [11], "isInherited": true}, "stroke": {"values": ["inherit", "initial", "unset"], "supports": [2, 11], "isInherited": true}, "text-decoration-line": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-webkit-background-size": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "padding-bottom": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-image-slice": {"values": ["inherit", "initial", "unset"], "supports": [7, 8], "isInherited": false}, "-webkit-transition-delay": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "background-repeat": {"values": ["inherit", "initial", "no-repeat", "repeat", "repeat-x", "repeat-y", "round", "space", "unset"], "supports": [], "isInherited": false}, "flex-basis": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-border-right-colors": {"values": ["inherit", "initial", "unset"], "supports": [2], "isInherited": false}, "-moz-image-region": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "-webkit-transform-origin": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "vector-effect": {"values": ["inherit", "initial", "non-scaling-stroke", "none", "unset"], "supports": [], "isInherited": false}, "-moz-margin-end": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-border-image": {"values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "supports": [4, 5, 6, 7, 8, 11], "isInherited": false}, "-moz-border-end-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "ruby-position": {"values": ["inherit", "initial", "over", "under", "unset"], "supports": [], "isInherited": true}, "inline-size": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "outline": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "auto", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "text-decoration": {"values": ["COLOR", "-moz-none", "-moz-use-text-color", "currentColor", "dashed", "dotted", "double", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "solid", "transparent", "unset", "wavy"], "supports": [2], "isInherited": false}, "transition-duration": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "order": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "ime-mode": {"values": ["active", "auto", "disabled", "inactive", "inherit", "initial", "normal", "unset"], "supports": [], "isInherited": false}, "counter-reset": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "flood-opacity": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "flex-direction": {"values": ["column", "column-reverse", "inherit", "initial", "row", "row-reverse", "unset"], "supports": [], "isInherited": false}, "-webkit-text-stroke-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": true}, "font-variant-numeric": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "-webkit-flex-wrap": {"values": ["inherit", "initial", "nowrap", "unset", "wrap", "wrap-reverse"], "supports": [], "isInherited": false}, "min-height": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "left": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-mask": {"supports": [4, 5, 6, 8, 11], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "add", "alpha", "border-box", "content-box", "exclude", "inherit", "initial", "intersect", "linear-gradient", "luminance", "match-source", "no-repeat", "none", "padding-box", "radial-gradient", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "round", "space", "subtract", "unset", "url"], "isInherited": false}, "stroke-width": {"values": ["inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": true}, "-moz-hyphens": {"values": ["auto", "inherit", "initial", "manual", "none", "unset"], "supports": [], "isInherited": true}, "background-origin": {"values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "supports": [], "isInherited": false}, "-moz-box-direction": {"values": ["inherit", "initial", "normal", "reverse", "unset"], "supports": [], "isInherited": false}, "border-inline-end-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "marker-offset": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6], "isInherited": false}, "-webkit-background-clip": {"values": ["border-box", "content-box", "inherit", "initial", "padding-box", "text", "unset"], "supports": [], "isInherited": false}, "border-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "flex": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": false}, "margin-inline-end": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-appearance": {"values": ["-moz-gtk-info-bar", "-moz-mac-disclosure-button-closed", "-moz-mac-disclosure-button-open", "-moz-mac-fullscreen-button", "-moz-mac-help-button", "-moz-mac-source-list", "-moz-mac-vibrancy-dark", "-moz-mac-vibrancy-light", "-moz-win-borderless-glass", "-moz-win-browsertabbar-toolbox", "-moz-win-communications-toolbox", "-moz-win-exclude-glass", "-moz-win-glass", "-moz-win-media-toolbox", "-moz-window-button-box", "-moz-window-button-box-maximized", "-moz-window-button-close", "-moz-window-button-maximize", "-moz-window-button-minimize", "-moz-window-button-restore", "-moz-window-frame-bottom", "-moz-window-frame-left", "-moz-window-frame-right", "-moz-window-titlebar", "-moz-window-titlebar-maximized", "button", "button-arrow-down", "button-arrow-next", "button-arrow-previous", "button-arrow-up", "button-bevel", "button-focus", "caret", "checkbox", "checkbox-container", "checkbox-label", "checkmenuitem", "dialog", "dualbutton", "groupbox", "inherit", "initial", "listbox", "listitem", "menuarrow", "menubar", "menucheckbox", "menuimage", "menuitem", "menuitemtext", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menupopup", "menuradio", "menuseparator", "meterbar", "meterchunk", "none", "number-input", "progressbar", "progressbar-vertical", "progresschunk", "progresschunk-vertical", "radio", "radio-container", "radio-label", "radiomenuitem", "range", "range-thumb", "resizer", "resizerpanel", "scale-horizontal", "scale-vertical", "scalethumb-horizontal", "scalethumb-vertical", "scalethumbend", "scalethumbstart", "scalethumbtick", "scrollbar", "scrollbar-horizontal", "scrollbar-small", "scrollbar-vertical", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbarthumb-horizontal", "scrollbarthumb-vertical", "scrollbartrack-horizontal", "scrollbartrack-vertical", "searchfield", "separator", "spinner", "spinner-downbutton", "spinner-textfield", "spinner-upbutton", "splitter", "statusbar", "statusbarpanel", "tab", "tab-scroll-arrow-back", "tab-scroll-arrow-forward", "tabpanel", "tabpanels", "textfield", "textfield-multiline", "toolbar", "toolbarbutton", "toolbarbutton-dropdown", "toolbargripper", "toolbox", "tooltip", "treeheader", "treeheadercell", "treeheadersortarrow", "treeitem", "treeline", "treetwisty", "treetwistyopen", "treeview", "unset", "window"], "supports": [], "isInherited": false}, "box-decoration-break": {"values": ["clone", "inherit", "initial", "slice", "unset"], "supports": [], "isInherited": false}, "text-indent": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": true}, "hyphens": {"values": ["auto", "inherit", "initial", "manual", "none", "unset"], "supports": [], "isInherited": true}, "-moz-perspective": {"values": ["inherit", "initial", "none", "unset"], "supports": [6], "isInherited": false}, "-webkit-animation-timing-function": {"values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "text-transform": {"values": ["capitalize", "full-width", "inherit", "initial", "lowercase", "none", "unset", "uppercase"], "supports": [], "isInherited": true}, "font-size": {"values": ["-moz-calc", "calc", "inherit", "initial", "large", "larger", "medium", "small", "smaller", "unset", "x-large", "x-small", "xx-large", "xx-small"], "supports": [6, 8], "isInherited": true}, "-webkit-animation-name": {"values": ["inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "-moz-border-start": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "mask-composite": {"supports": [], "values": ["add", "exclude", "inherit", "initial", "intersect", "subtract", "unset"], "isInherited": false}, "-webkit-text-stroke": {"values": ["COLOR", "-moz-calc", "calc", "currentColor", "hsl", "hsla", "inherit", "initial", "medium", "rgb", "rgba", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": true}, "padding-top": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-flex-shrink": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "color-adjust": {"values": ["economy", "exact", "inherit", "initial", "unset"], "supports": [], "isInherited": true}, "grid-template-rows": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "content": {"values": ["inherit", "initial", "unset"], "supports": [11], "isInherited": false}, "padding-right": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-transform": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "marker-mid": {"values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": true}, "-moz-column-gap": {"values": ["-moz-calc", "calc", "inherit", "initial", "normal", "unset"], "supports": [6], "isInherited": false}, "-moz-border-start-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "clip-rule": {"values": ["evenodd", "inherit", "initial", "nonzero", "unset"], "supports": [], "isInherited": true}, "font-family": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "block-size": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "offset-inline-start": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "padding-block-end": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "transition": {"values": ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset"], "supports": [9, 10], "isInherited": false}, "filter": {"values": ["inherit", "initial", "unset"], "supports": [11], "isInherited": false}, "border-right-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-webkit-flex-direction": {"values": ["column", "column-reverse", "inherit", "initial", "row", "row-reverse", "unset"], "supports": [], "isInherited": false}, "-webkit-mask-composite": {"supports": [], "values": ["add", "exclude", "inherit", "initial", "intersect", "subtract", "unset"], "isInherited": false}, "mix-blend-mode": {"values": ["color", "color-burn", "color-dodge", "darken", "difference", "exclusion", "hard-light", "hue", "inherit", "initial", "lighten", "luminosity", "multiply", "normal", "overlay", "saturation", "screen", "soft-light", "unset"], "supports": [], "isInherited": false}, "color-interpolation": {"values": ["auto", "inherit", "initial", "linearrgb", "srgb", "unset"], "supports": [], "isInherited": true}, "border-top-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "fill-opacity": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": true}, "marker-start": {"values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": true}, "border-bottom-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-moz-column-rule-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "clear": {"values": ["both", "inherit", "initial", "inline-end", "inline-start", "left", "none", "right", "unset"], "supports": [], "isInherited": false}, "grid-area": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "padding-inline-start": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-border-end": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "background-clip": {"values": ["border-box", "content-box", "inherit", "initial", "padding-box", "text", "unset"], "supports": [], "isInherited": false}, "-webkit-text-fill-color": {"values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": true}, "border-block-start-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "top": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "max-inline-size": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset"], "supports": [6, 8], "isInherited": false}, "border-inline-start-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-moz-box-flex": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "animation-play-state": {"values": ["inherit", "initial", "paused", "running", "unset"], "supports": [], "isInherited": false}, "padding": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "dominant-baseline": {"values": ["alphabetic", "auto", "central", "hanging", "ideographic", "inherit", "initial", "mathematical", "middle", "no-change", "reset-size", "text-after-edge", "text-before-edge", "unset", "use-script"], "supports": [], "isInherited": false}, "background-attachment": {"values": ["fixed", "inherit", "initial", "local", "scroll", "unset"], "supports": [], "isInherited": false}, "-webkit-box-sizing": {"values": ["border-box", "content-box", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-webkit-box-flex": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "text-orientation": {"values": ["inherit", "initial", "mixed", "sideways", "sideways-right", "unset", "upright"], "supports": [], "isInherited": true}, "-moz-margin-start": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "isolation": {"values": ["auto", "inherit", "initial", "isolate", "unset"], "supports": [], "isInherited": false}, "-moz-border-bottom-colors": {"values": ["inherit", "initial", "unset"], "supports": [2], "isInherited": false}, "-moz-column-rule-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "scroll-snap-type-y": {"values": ["inherit", "initial", "mandatory", "none", "proximity", "unset"], "supports": [], "isInherited": false}, "-webkit-border-bottom-right-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-column-count": {"values": ["auto", "inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "border-left-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "grid-column-end": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "background-blend-mode": {"values": ["color", "color-burn", "color-dodge", "darken", "difference", "exclusion", "hard-light", "hue", "inherit", "initial", "lighten", "luminosity", "multiply", "normal", "overlay", "saturation", "screen", "soft-light", "unset"], "supports": [], "isInherited": false}, "vertical-align": {"values": ["-moz-calc", "-moz-middle-with-baseline", "baseline", "bottom", "calc", "inherit", "initial", "middle", "sub", "super", "text-bottom", "text-top", "top", "unset"], "supports": [6, 8], "isInherited": false}, "clip": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "grid-auto-rows": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "margin-left": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "animation-name": {"values": ["inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "border-image-source": {"values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "supports": [4, 5, 11], "isInherited": false}, "border": {"values": ["COLOR", "-moz-calc", "-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "linear-gradient", "medium", "none", "outset", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset", "url"], "supports": [2, 6], "isInherited": false}, "-webkit-transition-timing-function": {"values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "margin-bottom": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "animation": {"values": ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset"], "supports": [7, 9, 10], "isInherited": false}, "font-weight": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": true}, "border-block-start-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "mask-type": {"values": ["alpha", "inherit", "initial", "luminance", "unset"], "supports": [], "isInherited": false}, "margin-block-end": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "min-inline-size": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "object-position": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "page-break-after": {"values": ["always", "auto", "avoid", "inherit", "initial", "left", "right", "unset"], "supports": [], "isInherited": false}, "transition-property": {"values": ["all", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "-moz-float-edge": {"values": ["content-box", "inherit", "initial", "margin-box", "unset"], "supports": [], "isInherited": false}, "white-space": {"values": ["-moz-pre-space", "inherit", "initial", "normal", "nowrap", "pre", "pre-line", "pre-wrap", "unset"], "supports": [], "isInherited": true}, "-moz-binding": {"values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": false}, "ruby-align": {"values": ["center", "inherit", "initial", "space-around", "space-between", "start", "unset"], "supports": [], "isInherited": true}, "font-kerning": {"values": ["auto", "inherit", "initial", "none", "normal", "unset"], "supports": [], "isInherited": true}, "border-block-end": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "animation-timing-function": {"values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "-webkit-border-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "animation-iteration-count": {"values": ["infinite", "inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-webkit-animation-direction": {"values": ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset"], "supports": [], "isInherited": false}, "justify-self": {"values": ["auto", "baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "-moz-border-top-colors": {"values": ["inherit", "initial", "unset"], "supports": [2], "isInherited": false}, "transition-timing-function": {"values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "-moz-transition-duration": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "scroll-snap-coordinate": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-box-orient": {"values": ["block-axis", "horizontal", "inherit", "initial", "inline-axis", "unset", "vertical"], "supports": [], "isInherited": false}, "counter-increment": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-webkit-transform-style": {"values": ["flat", "inherit", "initial", "preserve-3d", "unset"], "supports": [], "isInherited": false}, "-moz-transition-timing-function": {"values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "grid-auto-columns": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-align-content": {"values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "space-around", "space-between", "space-evenly", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "font": {"values": ["-moz-block-height", "-moz-calc", "all-petite-caps", "all-small-caps", "auto", "calc", "condensed", "expanded", "extra-condensed", "extra-expanded", "inherit", "initial", "italic", "large", "larger", "medium", "none", "normal", "oblique", "petite-caps", "semi-condensed", "semi-expanded", "small", "small-caps", "smaller", "sub", "super", "titling-caps", "ultra-condensed", "ultra-expanded", "unicase", "unset", "x-large", "x-small", "xx-large", "xx-small"], "supports": [6, 7, 8], "isInherited": true}, "flex-wrap": {"values": ["inherit", "initial", "nowrap", "unset", "wrap", "wrap-reverse"], "supports": [], "isInherited": false}, "grid-row-start": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "list-style-image": {"values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": true}, "text-emphasis-position": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "border-right": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "font-style": {"values": ["inherit", "initial", "italic", "normal", "oblique", "unset"], "supports": [], "isInherited": true}, "box-shadow": {"values": ["inherit", "initial", "unset"], "supports": [2, 6], "isInherited": false}, "align-self": {"values": ["auto", "baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "text-emphasis-color": {"values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": true}, "border-bottom": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "border-spacing": {"values": ["inherit", "initial", "unset"], "supports": [6], "isInherited": true}, "-webkit-border-top-right-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "margin-inline-start": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "grid-row-end": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "perspective-origin": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "page-break-inside": {"values": ["auto", "avoid", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "scroll-behavior": {"values": ["auto", "inherit", "initial", "smooth", "unset"], "supports": [], "isInherited": false}, "-moz-backface-visibility": {"values": ["hidden", "inherit", "initial", "unset", "visible"], "supports": [], "isInherited": false}, "-moz-outline-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "mask-clip": {"supports": [], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "isInherited": false}, "grid-row": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "border-bottom-right-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "line-height": {"values": ["-moz-block-height", "-moz-calc", "calc", "inherit", "initial", "normal", "unset"], "supports": [6, 7, 8], "isInherited": true}, "stroke-linejoin": {"values": ["bevel", "inherit", "initial", "miter", "round", "unset"], "supports": [], "isInherited": true}, "text-align-last": {"values": ["auto", "center", "end", "inherit", "initial", "justify", "left", "right", "start", "unset"], "supports": [], "isInherited": true}, "word-spacing": {"values": ["-moz-calc", "calc", "inherit", "initial", "normal", "unset"], "supports": [6, 8], "isInherited": true}, "transform-style": {"values": ["flat", "inherit", "initial", "preserve-3d", "unset"], "supports": [], "isInherited": false}, "border-bottom-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "font-language-override": {"values": ["inherit", "initial", "normal", "unset"], "supports": [], "isInherited": true}, "-moz-outline-radius-topleft": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-image": {"values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "supports": [4, 5, 6, 7, 8, 11], "isInherited": false}, "caption-side": {"values": ["bottom", "bottom-outside", "inherit", "initial", "left", "right", "top", "top-outside", "unset"], "supports": [], "isInherited": true}, "-webkit-mask-position": {"supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "border-inline-end-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-webkit-border-image": {"values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "supports": [4, 5, 6, 7, 8, 11], "isInherited": false}, "font-synthesis": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "grid-template": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-mask-repeat": {"supports": [], "values": ["inherit", "initial", "no-repeat", "repeat", "repeat-x", "repeat-y", "round", "space", "unset"], "isInherited": false}, "-webkit-justify-content": {"values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "space-around", "space-between", "space-evenly", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "text-decoration-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "color": {"values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": true}, "-moz-border-end-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "height": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "margin-right": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-border-bottom-left-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-transform": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "border-bottom-left-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "fill-rule": {"values": ["evenodd", "inherit", "initial", "nonzero", "unset"], "supports": [], "isInherited": true}, "min-width": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "empty-cells": {"values": ["hide", "inherit", "initial", "show", "unset"], "supports": [], "isInherited": true}, "direction": {"values": ["inherit", "initial", "ltr", "rtl", "unset"], "supports": [], "isInherited": true}, "clip-path": {"values": ["inherit", "initial", "unset"], "supports": [11], "isInherited": false}, "-webkit-mask-size": {"supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "-moz-box-orient": {"values": ["block-axis", "horizontal", "inherit", "initial", "inline-axis", "unset", "vertical"], "supports": [], "isInherited": false}, "z-index": {"values": ["auto", "inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "background-position-y": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "text-decoration-style": {"values": ["-moz-none", "dashed", "dotted", "double", "inherit", "initial", "solid", "unset", "wavy"], "supports": [], "isInherited": false}, "grid-template-areas": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-moz-perspective-origin": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-animation-direction": {"values": ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset"], "supports": [], "isInherited": false}, "font-size-adjust": {"values": ["inherit", "initial", "none", "unset"], "supports": [7], "isInherited": true}, "cursor": {"values": ["inherit", "initial", "unset"], "supports": [11], "isInherited": true}, "margin": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-animation": {"values": ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset"], "supports": [7, 9, 10], "isInherited": false}, "-moz-control-character-visibility": {"values": ["hidden", "inherit", "initial", "unset", "visible"], "supports": [], "isInherited": true}, "letter-spacing": {"values": ["-moz-calc", "calc", "inherit", "initial", "normal", "unset"], "supports": [6], "isInherited": true}, "-moz-transition-delay": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "will-change": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "transform-origin": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "font-variant-ligatures": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "padding-block-start": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-animation-duration": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "border-block-end-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-webkit-mask-origin": {"supports": [], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "isInherited": false}, "word-break": {"values": ["break-all", "inherit", "initial", "keep-all", "normal", "unset"], "supports": [], "isInherited": true}, "table-layout": {"values": ["auto", "fixed", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "text-overflow": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-webkit-flex": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": false}, "grid-auto-flow": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "border-top-right-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-image-outset": {"values": ["inherit", "initial", "unset"], "supports": [6, 7], "isInherited": false}, "mask-size": {"supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "touch-action": {"values": ["auto", "inherit", "initial", "manipulation", "none", "pan-x", "pan-y", "unset"], "supports": [], "isInherited": false}, "border-right-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "backface-visibility": {"values": ["hidden", "inherit", "initial", "unset", "visible"], "supports": [], "isInherited": false}, "background-image": {"values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "supports": [4, 5, 11], "isInherited": false}, "-moz-box-ordinal-group": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-webkit-transition-property": {"values": ["all", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "writing-mode": {"values": ["horizontal-tb", "inherit", "initial", "lr", "lr-tb", "rl", "rl-tb", "sideways-lr", "sideways-rl", "tb", "tb-rl", "unset", "vertical-lr", "vertical-rl"], "supports": [], "isInherited": true}, "stroke-opacity": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": true}, "box-sizing": {"values": ["border-box", "content-box", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "margin-top": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "position": {"values": ["absolute", "fixed", "inherit", "initial", "relative", "static", "sticky", "unset"], "supports": [], "isInherited": false}, "list-style-position": {"values": ["inherit", "initial", "inside", "outside", "unset"], "supports": [], "isInherited": true}, "-webkit-box-pack": {"values": ["center", "end", "inherit", "initial", "justify", "start", "unset"], "supports": [], "isInherited": false}, "quotes": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "border-top": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "-moz-animation-delay": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "-webkit-transition": {"values": ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset"], "supports": [9, 10], "isInherited": false}, "-moz-window-dragging": {"values": ["default", "drag", "inherit", "initial", "no-drag", "unset"], "supports": [], "isInherited": false}, "lighting-color": {"values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "background-size": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-border-top-left-radius": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-outline-radius-bottomleft": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "mask-position-x": {"supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "mask-position-y": {"supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "justify-content": {"values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "space-around", "space-between", "space-evenly", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "animation-fill-mode": {"values": ["backwards", "both", "forwards", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "-webkit-filter": {"values": ["inherit", "initial", "unset"], "supports": [11], "isInherited": false}, "word-wrap": {"values": ["break-word", "inherit", "initial", "normal", "unset"], "supports": [], "isInherited": true}, "grid": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "background": {"values": ["COLOR", "-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "border-box", "content-box", "currentColor", "fixed", "hsl", "hsla", "inherit", "initial", "linear-gradient", "local", "no-repeat", "none", "padding-box", "radial-gradient", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "rgb", "rgba", "round", "scroll", "space", "text", "transparent", "unset", "url"], "supports": [2, 4, 5, 6, 8, 11], "isInherited": false}, "margin-block-start": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "grid-column-start": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "text-align": {"values": ["-moz-center", "-moz-left", "-moz-right", "center", "end", "inherit", "initial", "justify", "left", "right", "start", "unset"], "supports": [], "isInherited": true}, "marker-end": {"values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": true}, "justify-items": {"values": ["auto", "baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "mask-position": {"supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "-moz-columns": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 7], "isInherited": false}, "-moz-outline-radius-topright": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "right": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-border-left-colors": {"values": ["inherit", "initial", "unset"], "supports": [2], "isInherited": false}, "-webkit-mask-position-x": {"supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "-webkit-transition-duration": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "border-top-width": {"values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "bottom": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-block-end-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "-webkit-order": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-moz-animation-iteration-count": {"values": ["infinite", "inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-moz-animation-timing-function": {"values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "background-color": {"values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "-webkit-backface-visibility": {"values": ["hidden", "inherit", "initial", "unset", "visible"], "supports": [], "isInherited": false}, "animation-delay": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "unicode-bidi": {"values": ["-moz-isolate", "-moz-isolate-override", "-moz-plaintext", "bidi-override", "embed", "inherit", "initial", "isolate", "isolate-override", "normal", "plaintext", "unset"], "supports": [], "isInherited": false}, "text-shadow": {"values": ["inherit", "initial", "unset"], "supports": [2, 6], "isInherited": true}, "-moz-user-modify": {"values": ["inherit", "initial", "read-only", "read-write", "unset", "write-only"], "supports": [], "isInherited": true}, "-webkit-box-direction": {"values": ["inherit", "initial", "normal", "reverse", "unset"], "supports": [], "isInherited": false}, "image-rendering": {"values": ["-moz-crisp-edges", "auto", "inherit", "initial", "optimizequality", "optimizespeed", "unset"], "supports": [], "isInherited": true}, "border-inline-end": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "grid-gap": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-animation-name": {"values": ["inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "pointer-events": {"values": ["all", "auto", "fill", "inherit", "initial", "none", "painted", "stroke", "unset", "visible", "visiblefill", "visiblepainted", "visiblestroke"], "supports": [], "isInherited": true}, "border-image-width": {"values": ["inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": false}, "border-inline-start": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "min-block-size": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-mask-clip": {"supports": [], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "isInherited": false}, "-webkit-mask-image": {"supports": [4, 5, 11], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "isInherited": false}, "float": {"values": ["inherit", "initial", "inline-end", "inline-start", "left", "none", "right", "unset"], "supports": [], "isInherited": false}, "max-height": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset"], "supports": [6, 8], "isInherited": false}, "outline-offset": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6], "isInherited": false}, "-moz-transform-style": {"values": ["flat", "inherit", "initial", "preserve-3d", "unset"], "supports": [], "isInherited": false}, "overflow-wrap": {"values": ["break-word", "inherit", "initial", "normal", "unset"], "supports": [], "isInherited": true}, "fill": {"values": ["inherit", "initial", "unset"], "supports": [2, 11], "isInherited": true}, "scroll-snap-type": {"values": ["inherit", "initial", "mandatory", "none", "proximity", "unset"], "supports": [], "isInherited": false}, "text-emphasis-style": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "transform": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-moz-text-align-last": {"values": ["auto", "center", "end", "inherit", "initial", "justify", "left", "right", "start", "unset"], "supports": [], "isInherited": true}, "width": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "stroke-miterlimit": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": true}, "stop-opacity": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "border-top-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "background-position": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "scroll-snap-type-x": {"values": ["inherit", "initial", "mandatory", "none", "proximity", "unset"], "supports": [], "isInherited": false}, "object-fit": {"values": ["contain", "cover", "fill", "inherit", "initial", "none", "scale-down", "unset"], "supports": [], "isInherited": false}, "-moz-box-sizing": {"values": ["border-box", "content-box", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "offset-block-start": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-background-origin": {"values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "supports": [], "isInherited": false}, "-webkit-align-items": {"values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "-moz-padding-start": {"values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "transition-delay": {"values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "border-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "mask-repeat": {"supports": [], "values": ["inherit", "initial", "no-repeat", "repeat", "repeat-x", "repeat-y", "round", "space", "unset"], "isInherited": false}, "overflow": {"values": ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible"], "supports": [], "isInherited": false}, "mask-origin": {"supports": [], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "isInherited": false}, "-moz-force-broken-image-icon": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "grid-template-columns": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-align-self": {"values": ["auto", "baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "-webkit-perspective-origin": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-block-start": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "display": {"values": ["-moz-box", "-moz-deck", "-moz-grid", "-moz-grid-group", "-moz-grid-line", "-moz-groupbox", "-moz-inline-box", "-moz-inline-grid", "-moz-inline-stack", "-moz-popup", "-moz-stack", "-webkit-box", "-webkit-flex", "-webkit-inline-box", "-webkit-inline-flex", "block", "contents", "flex", "grid", "inherit", "initial", "inline", "inline-block", "inline-flex", "inline-grid", "inline-table", "list-item", "none", "ruby", "ruby-base", "ruby-base-container", "ruby-text", "ruby-text-container", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "unset"], "supports": [], "isInherited": false}, "-webkit-box-ordinal-group": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-moz-column-width": {"values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6], "isInherited": false}, "border-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "-webkit-flex-basis": {"values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "stroke-dashoffset": {"values": ["inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": true}, "-moz-transform-origin": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-text-size-adjust": {"values": ["auto", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": true}, "border-left-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "overflow-y": {"values": ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible"], "supports": [], "isInherited": false}, "overflow-x": {"values": ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible"], "supports": [], "isInherited": false}, "-moz-user-select": {"values": ["-moz-all", "-moz-none", "-moz-text", "all", "auto", "element", "elements", "inherit", "initial", "none", "text", "toggle", "tri-state", "unset"], "supports": [], "isInherited": false}, "-moz-column-rule": {"values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "-moz-outline-radius-bottomright": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-column-rule-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "-moz-transition": {"values": ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset"], "supports": [9, 10], "isInherited": false}, "opacity": {"values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-webkit-perspective": {"values": ["inherit", "initial", "none", "unset"], "supports": [6], "isInherited": false}, "-webkit-text-stroke-color": {"values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": true}, "align-content": {"values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "space-around", "space-between", "space-evenly", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "scroll-snap-points-y": {"values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-moz-transition-property": {"values": ["all", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "border-bottom-style": {"values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "-moz-animation-play-state": {"values": ["inherit", "initial", "paused", "running", "unset"], "supports": [], "isInherited": false}, "mask": {"values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "add", "alpha", "border-box", "content-box", "exclude", "inherit", "initial", "intersect", "linear-gradient", "luminance", "match-source", "no-repeat", "none", "padding-box", "radial-gradient", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "round", "space", "subtract", "unset", "url"], "supports": [4, 5, 6, 8, 11], "isInherited": false}, "background-position-x": {"values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "stop-color": {"values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "border-block-end-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "stroke-dasharray": {"values": ["inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": true}, "border-inline-start-color": {"values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}};
+exports.CSS_PROPERTIES = {"all": {"subproperties": ["align-content", "align-items", "align-self", "animation-delay", "animation-direction", "animation-duration", "animation-fill-mode", "animation-iteration-count", "animation-name", "animation-play-state", "animation-timing-function", "-moz-appearance", "backface-visibility", "background-attachment", "background-blend-mode", "background-clip", "background-color", "background-image", "background-origin", "background-position-x", "background-position-y", "background-repeat", "background-size", "-moz-binding", "block-size", "border-block-end-color", "border-block-end-style", "border-block-end-width", "border-block-start-color", "border-block-start-style", "border-block-start-width", "border-bottom-color", "-moz-border-bottom-colors", "border-bottom-left-radius", "border-bottom-right-radius", "border-bottom-style", "border-bottom-width", "border-collapse", "border-image-outset", "border-image-repeat", "border-image-slice", "border-image-source", "border-image-width", "border-inline-end-color", "border-inline-end-style", "border-inline-end-width", "border-inline-start-color", "border-inline-start-style", "border-inline-start-width", "border-left-color", "-moz-border-left-colors", "border-left-style", "border-left-width", "border-right-color", "-moz-border-right-colors", "border-right-style", "border-right-width", "border-spacing", "border-top-color", "-moz-border-top-colors", "border-top-left-radius", "border-top-right-radius", "border-top-style", "border-top-width", "bottom", "-moz-box-align", "box-decoration-break", "-moz-box-direction", "-moz-box-flex", "-moz-box-ordinal-group", "-moz-box-orient", "-moz-box-pack", "box-shadow", "box-sizing", "caption-side", "clear", "clip", "clip-path", "clip-rule", "color", "color-adjust", "color-interpolation", "color-interpolation-filters", "-moz-column-count", "-moz-column-fill", "-moz-column-gap", "-moz-column-rule-color", "-moz-column-rule-style", "-moz-column-rule-width", "-moz-column-width", "contain", "content", "-moz-control-character-visibility", "counter-increment", "counter-reset", "cursor", "display", "dominant-baseline", "empty-cells", "fill", "fill-opacity", "fill-rule", "filter", "flex-basis", "flex-direction", "flex-grow", "flex-shrink", "flex-wrap", "float", "-moz-float-edge", "flood-color", "flood-opacity", "font-family", "font-feature-settings", "font-kerning", "font-language-override", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", "font-weight", "-moz-force-broken-image-icon", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows", "grid-column-end", "grid-column-gap", "grid-column-start", "grid-row-end", "grid-row-gap", "grid-row-start", "grid-template-areas", "grid-template-columns", "grid-template-rows", "height", "hyphens", "initial-letter", "image-orientation", "-moz-image-region", "image-rendering", "ime-mode", "inline-size", "isolation", "justify-content", "justify-items", "justify-self", "left", "letter-spacing", "lighting-color", "line-height", "list-style-image", "list-style-position", "list-style-type", "margin-block-end", "margin-block-start", "margin-bottom", "margin-inline-end", "margin-inline-start", "margin-left", "margin-right", "margin-top", "marker-end", "marker-mid", "marker-offset", "marker-start", "mask-clip", "mask-composite", "mask-image", "mask-mode", "mask-origin", "mask-position-x", "mask-position-y", "mask-repeat", "mask-size", "mask-type", "max-block-size", "max-height", "max-inline-size", "max-width", "min-block-size", "-moz-min-font-size-ratio", "min-height", "min-inline-size", "min-width", "mix-blend-mode", "object-fit", "object-position", "offset-block-end", "offset-block-start", "offset-inline-end", "offset-inline-start", "opacity", "order", "-moz-orient", "-moz-osx-font-smoothing", "outline-color", "outline-offset", "-moz-outline-radius-bottomleft", "-moz-outline-radius-bottomright", "-moz-outline-radius-topleft", "-moz-outline-radius-topright", "outline-style", "outline-width", "overflow-clip-box", "overflow-x", "overflow-y", "padding-block-end", "padding-block-start", "padding-bottom", "padding-inline-end", "padding-inline-start", "padding-left", "padding-right", "padding-top", "page-break-after", "page-break-before", "page-break-inside", "paint-order", "perspective", "perspective-origin", "pointer-events", "position", "quotes", "resize", "right", "ruby-align", "ruby-position", "scroll-behavior", "scroll-snap-coordinate", "scroll-snap-destination", "scroll-snap-points-x", "scroll-snap-points-y", "scroll-snap-type-x", "scroll-snap-type-y", "shape-outside", "shape-rendering", "-moz-stack-sizing", "stop-color", "stop-opacity", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "-x-system-font", "-moz-tab-size", "table-layout", "text-align", "text-align-last", "text-anchor", "text-combine-upright", "text-decoration-color", "text-decoration-line", "text-decoration-style", "text-emphasis-color", "text-emphasis-position", "text-emphasis-style", "-webkit-text-fill-color", "text-indent", "text-orientation", "text-overflow", "text-rendering", "text-shadow", "-moz-text-size-adjust", "-webkit-text-stroke-color", "-webkit-text-stroke-width", "text-transform", "top", "-moz-top-layer", "touch-action", "transform", "transform-box", "transform-origin", "transform-style", "transition-delay", "transition-duration", "transition-property", "transition-timing-function", "-moz-user-focus", "-moz-user-input", "-moz-user-modify", "-moz-user-select", "vector-effect", "vertical-align", "visibility", "white-space", "width", "will-change", "-moz-window-dragging", "-moz-window-shadow", "word-break", "word-spacing", "overflow-wrap", "writing-mode", "z-index"], "values": ["COLOR", "-moz-all", "-moz-available", "-moz-block-height", "-moz-box", "-moz-calc", "-moz-center", "-moz-crisp-edges", "-moz-deck", "-moz-element", "-moz-fit-content", "-moz-grid", "-moz-grid-group", "-moz-grid-line", "-moz-groupbox", "-moz-gtk-info-bar", "-moz-hidden-unscrollable", "-moz-image-rect", "-moz-inline-box", "-moz-inline-grid", "-moz-inline-stack", "-moz-left", "-moz-linear-gradient", "-moz-mac-disclosure-button-closed", "-moz-mac-disclosure-button-open", "-moz-mac-fullscreen-button", "-moz-mac-help-button", "-moz-mac-source-list", "-moz-mac-vibrancy-dark", "-moz-mac-vibrancy-light", "-moz-max-content", "-moz-middle-with-baseline", "-moz-min-content", "-moz-none", "-moz-popup", "-moz-pre-space", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "-moz-right", "-moz-stack", "-moz-text", "-moz-use-text-color", "-moz-win-borderless-glass", "-moz-win-browsertabbar-toolbox", "-moz-win-communications-toolbox", "-moz-win-exclude-glass", "-moz-win-glass", "-moz-win-media-toolbox", "-moz-window-button-box", "-moz-window-button-box-maximized", "-moz-window-button-close", "-moz-window-button-maximize", "-moz-window-button-minimize", "-moz-window-button-restore", "-moz-window-frame-bottom", "-moz-window-frame-left", "-moz-window-frame-right", "-moz-window-titlebar", "-moz-window-titlebar-maximized", "-webkit-box", "-webkit-flex", "-webkit-inline-box", "-webkit-inline-flex", "absolute", "active", "add", "all", "all-petite-caps", "all-small-caps", "alpha", "alphabetic", "alternate", "alternate-reverse", "always", "auto", "avoid", "backwards", "balance", "baseline", "bevel", "block", "block-axis", "border-box", "both", "bottom", "bottom-outside", "break-all", "break-word", "butt", "button", "button-arrow-down", "button-arrow-next", "button-arrow-previous", "button-arrow-up", "button-bevel", "button-focus", "calc", "capitalize", "caret", "center", "central", "checkbox", "checkbox-container", "checkbox-label", "checkmenuitem", "clone", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", "condensed", "contain", "content-box", "contents", "cover", "crispedges", "cubic-bezier", "currentColor", "darken", "dashed", "default", "dialog", "difference", "disabled", "dotted", "double", "drag", "dualbutton", "ease", "ease-in", "ease-in-out", "ease-out", "economy", "element", "elements", "enabled", "end", "evenodd", "exact", "exclude", "exclusion", "expanded", "extra-condensed", "extra-expanded", "fill", "fill-box", "fixed", "flat", "flex", "flex-end", "flex-start", "forwards", "full-width", "geometricprecision", "grid", "groove", "groupbox", "hanging", "hard-light", "hidden", "hide", "horizontal", "horizontal-tb", "hsl", "hsla", "hue", "ideographic", "ignore", "inactive", "infinite", "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-end", "inline-flex", "inline-grid", "inline-start", "inline-table", "inset", "inside", "intersect", "isolate", "italic", "justify", "keep-all", "large", "larger", "last-baseline", "left", "lighten", "linear", "linear-gradient", "linearrgb", "list-item", "listbox", "listitem", "local", "lowercase", "lr", "lr-tb", "luminance", "luminosity", "mandatory", "manipulation", "manual", "margin-box", "match-source", "mathematical", "medium", "menuarrow", "menubar", "menucheckbox", "menuimage", "menuitem", "menuitemtext", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menupopup", "menuradio", "menuseparator", "meterbar", "meterchunk", "middle", "miter", "mixed", "multiply", "no-change", "no-drag", "no-repeat", "non-scaling-stroke", "none", "nonzero", "normal", "nowrap", "number-input", "oblique", "optimizelegibility", "optimizequality", "optimizespeed", "outset", "outside", "over", "overlay", "padding-box", "painted", "pan-x", "pan-y", "paused", "petite-caps", "pre", "pre-line", "pre-wrap", "preserve-3d", "progressbar", "progressbar-vertical", "progresschunk", "progresschunk-vertical", "proximity", "radial-gradient", "radio", "radio-container", "radio-label", "radiomenuitem", "range", "range-thumb", "read-only", "read-write", "relative", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "reset-size", "resizer", "resizerpanel", "reverse", "rgb", "rgba", "ridge", "right", "rl", "rl-tb", "round", "row", "row-reverse", "ruby", "ruby-base", "ruby-base-container", "ruby-text", "ruby-text-container", "running", "saturation", "scale-down", "scale-horizontal", "scale-vertical", "scalethumb-horizontal", "scalethumb-vertical", "scalethumbend", "scalethumbstart", "scalethumbtick", "screen", "scroll", "scrollbar", "scrollbar-horizontal", "scrollbar-small", "scrollbar-vertical", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbarthumb-horizontal", "scrollbarthumb-vertical", "scrollbartrack-horizontal", "scrollbartrack-vertical", "searchfield", "select-after", "select-all", "select-before", "select-menu", "select-same", "self-end", "self-start", "semi-condensed", "semi-expanded", "separate", "separator", "show", "sideways", "sideways-lr", "sideways-right", "sideways-rl", "slice", "small", "small-caps", "smaller", "smooth", "soft-light", "solid", "space", "space-around", "space-between", "space-evenly", "spinner", "spinner-downbutton", "spinner-textfield", "spinner-upbutton", "splitter", "square", "srgb", "start", "static", "statusbar", "statusbarpanel", "step-end", "step-start", "steps", "sticky", "stretch", "stretch-to-fit", "stroke", "sub", "subtract", "super", "tab", "tab-scroll-arrow-back", "tab-scroll-arrow-forward", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "tabpanel", "tabpanels", "tb", "tb-rl", "text", "text-after-edge", "text-before-edge", "text-bottom", "text-top", "textfield", "textfield-multiline", "thick", "thin", "titling-caps", "toggle", "toolbar", "toolbarbutton", "toolbarbutton-dropdown", "toolbargripper", "toolbox", "tooltip", "top", "top-outside", "transparent", "treeheader", "treeheadercell", "treeheadersortarrow", "treeitem", "treeline", "treetwisty", "treetwistyopen", "treeview", "tri-state", "ultra-condensed", "ultra-expanded", "under", "unicase", "unset", "uppercase", "upright", "url", "use-script", "vertical", "vertical-lr", "vertical-rl", "view-box", "visible", "visiblefill", "visiblepainted", "visiblestroke", "wavy", "window", "wrap", "wrap-reverse", "write-only", "x-large", "x-small", "xx-large", "xx-small"], "supports": [1, 2, 4, 5, 6, 7, 8, 9, 10, 11], "isInherited": false}, "mask-image": {"subproperties": ["mask-image"], "supports": [4, 5, 11], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "isInherited": false}, "-webkit-animation-iteration-count": {"subproperties": ["animation-iteration-count"], "values": ["infinite", "inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "font-feature-settings": {"subproperties": ["font-feature-settings"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "border-block-start-color": {"subproperties": ["border-block-start-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "-webkit-flex-grow": {"subproperties": ["flex-grow"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "scroll-snap-destination": {"subproperties": ["scroll-snap-destination"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-font-language-override": {"subproperties": ["font-language-override"], "values": ["inherit", "initial", "normal", "unset"], "supports": [], "isInherited": true}, "text-emphasis": {"subproperties": ["text-emphasis-style", "text-emphasis-color"], "values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": true}, "grid-row-gap": {"subproperties": ["grid-row-gap"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "font-variant-east-asian": {"subproperties": ["font-variant-east-asian"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "outline-width": {"subproperties": ["outline-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-webkit-flex-flow": {"subproperties": ["flex-direction", "flex-wrap"], "values": ["column", "column-reverse", "inherit", "initial", "nowrap", "row", "row-reverse", "unset", "wrap", "wrap-reverse"], "supports": [], "isInherited": false}, "grid-column-gap": {"subproperties": ["grid-column-gap"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-inline-start-style": {"subproperties": ["border-inline-start-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "scroll-snap-points-x": {"subproperties": ["scroll-snap-points-x"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "list-style-type": {"subproperties": ["list-style-type"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "padding-inline-end": {"subproperties": ["padding-inline-end"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-animation": {"subproperties": ["animation-duration", "animation-timing-function", "animation-delay", "animation-direction", "animation-fill-mode", "animation-iteration-count", "animation-play-state", "animation-name"], "values": ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset"], "supports": [7, 9, 10], "isInherited": false}, "-moz-border-start-width": {"subproperties": ["border-inline-start-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "page-break-before": {"subproperties": ["page-break-before"], "values": ["always", "auto", "avoid", "inherit", "initial", "left", "right", "unset"], "supports": [], "isInherited": false}, "flood-color": {"subproperties": ["flood-color"], "values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "text-anchor": {"subproperties": ["text-anchor"], "values": ["end", "inherit", "initial", "middle", "start", "unset"], "supports": [], "isInherited": true}, "-moz-box-pack": {"subproperties": ["-moz-box-pack"], "values": ["center", "end", "inherit", "initial", "justify", "start", "unset"], "supports": [], "isInherited": false}, "-webkit-user-select": {"subproperties": ["-moz-user-select"], "values": ["-moz-all", "-moz-none", "-moz-text", "all", "auto", "element", "elements", "inherit", "initial", "none", "text", "toggle", "tri-state", "unset"], "supports": [], "isInherited": false}, "-moz-border-end-style": {"subproperties": ["border-inline-end-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "padding-left": {"subproperties": ["padding-left"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-tab-size": {"subproperties": ["-moz-tab-size"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": true}, "perspective": {"subproperties": ["perspective"], "values": ["inherit", "initial", "none", "unset"], "supports": [6], "isInherited": false}, "max-block-size": {"subproperties": ["max-block-size"], "values": ["-moz-calc", "calc", "inherit", "initial", "none", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-animation-play-state": {"subproperties": ["animation-play-state"], "values": ["inherit", "initial", "paused", "running", "unset"], "supports": [], "isInherited": false}, "-moz-column-fill": {"subproperties": ["-moz-column-fill"], "values": ["auto", "balance", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-moz-stack-sizing": {"subproperties": ["-moz-stack-sizing"], "values": ["ignore", "inherit", "initial", "stretch-to-fit", "unset"], "supports": [], "isInherited": false}, "border-image-repeat": {"subproperties": ["border-image-repeat"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "font-variant-position": {"subproperties": ["font-variant-position"], "values": ["inherit", "initial", "normal", "sub", "super", "unset"], "supports": [], "isInherited": true}, "border-right-style": {"subproperties": ["border-right-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "-moz-box-align": {"subproperties": ["-moz-box-align"], "values": ["baseline", "center", "end", "inherit", "initial", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "border-left-style": {"subproperties": ["border-left-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "flex-flow": {"subproperties": ["flex-direction", "flex-wrap"], "values": ["column", "column-reverse", "inherit", "initial", "nowrap", "row", "row-reverse", "unset", "wrap", "wrap-reverse"], "supports": [], "isInherited": false}, "outline-color": {"subproperties": ["outline-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "font-variant-alternates": {"subproperties": ["font-variant-alternates"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "mask-mode": {"subproperties": ["mask-mode"], "supports": [], "values": ["alpha", "inherit", "initial", "luminance", "match-source", "unset"], "isInherited": false}, "flex-grow": {"subproperties": ["flex-grow"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-moz-font-feature-settings": {"subproperties": ["font-feature-settings"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "-webkit-box-shadow": {"subproperties": ["box-shadow"], "values": ["inherit", "initial", "unset"], "supports": [2, 6], "isInherited": false}, "max-width": {"subproperties": ["max-width"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset"], "supports": [6, 8], "isInherited": false}, "border-inline-end-style": {"subproperties": ["border-inline-end-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "grid-column": {"subproperties": ["grid-column-start", "grid-column-end"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "image-orientation": {"subproperties": ["image-orientation"], "values": ["inherit", "initial", "unset"], "supports": [1], "isInherited": true}, "animation-duration": {"subproperties": ["animation-duration"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "-moz-animation-fill-mode": {"subproperties": ["animation-fill-mode"], "values": ["backwards", "both", "forwards", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "-moz-user-input": {"subproperties": ["-moz-user-input"], "values": ["auto", "disabled", "enabled", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": true}, "-webkit-animation-delay": {"subproperties": ["animation-delay"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "shape-rendering": {"subproperties": ["shape-rendering"], "values": ["auto", "crispedges", "geometricprecision", "inherit", "initial", "optimizespeed", "unset"], "supports": [], "isInherited": true}, "flex-shrink": {"subproperties": ["flex-shrink"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "text-rendering": {"subproperties": ["text-rendering"], "values": ["auto", "geometricprecision", "inherit", "initial", "optimizelegibility", "optimizespeed", "unset"], "supports": [], "isInherited": true}, "align-items": {"subproperties": ["align-items"], "values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "border-collapse": {"subproperties": ["border-collapse"], "values": ["collapse", "inherit", "initial", "separate", "unset"], "supports": [], "isInherited": true}, "text-combine-upright": {"subproperties": ["text-combine-upright"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "offset-block-end": {"subproperties": ["offset-block-end"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-border-start-color": {"subproperties": ["border-inline-start-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "marker": {"subproperties": ["marker-start", "marker-mid", "marker-end"], "values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": true}, "-webkit-mask-position-y": {"subproperties": ["mask-position-y"], "supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "outline-style": {"subproperties": ["outline-style"], "values": ["auto", "dashed", "dotted", "double", "groove", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "color-interpolation-filters": {"subproperties": ["color-interpolation-filters"], "values": ["auto", "inherit", "initial", "linearrgb", "srgb", "unset"], "supports": [], "isInherited": true}, "-moz-padding-end": {"subproperties": ["padding-inline-end"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "font-stretch": {"subproperties": ["font-stretch"], "values": ["condensed", "expanded", "extra-condensed", "extra-expanded", "inherit", "initial", "normal", "semi-condensed", "semi-expanded", "ultra-condensed", "ultra-expanded", "unset"], "supports": [], "isInherited": true}, "-moz-orient": {"subproperties": ["-moz-orient"], "values": ["block", "horizontal", "inherit", "initial", "inline", "unset", "vertical"], "supports": [], "isInherited": false}, "font-variant": {"subproperties": ["font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position"], "values": ["all-petite-caps", "all-small-caps", "inherit", "initial", "normal", "petite-caps", "small-caps", "sub", "super", "titling-caps", "unicase", "unset"], "supports": [], "isInherited": true}, "-webkit-animation-fill-mode": {"subproperties": ["animation-fill-mode"], "values": ["backwards", "both", "forwards", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "-moz-animation-duration": {"subproperties": ["animation-duration"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "border-left": {"subproperties": ["border-left-width", "border-left-style", "border-left-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "visibility": {"subproperties": ["visibility"], "values": ["collapse", "hidden", "inherit", "initial", "unset", "visible"], "supports": [], "isInherited": true}, "-moz-user-focus": {"subproperties": ["-moz-user-focus"], "values": ["ignore", "inherit", "initial", "none", "normal", "select-after", "select-all", "select-before", "select-menu", "select-same", "unset"], "supports": [], "isInherited": true}, "transform-box": {"subproperties": ["transform-box"], "values": ["border-box", "fill-box", "inherit", "initial", "unset", "view-box"], "supports": [], "isInherited": false}, "font-variant-caps": {"subproperties": ["font-variant-caps"], "values": ["all-petite-caps", "all-small-caps", "inherit", "initial", "normal", "petite-caps", "small-caps", "titling-caps", "unicase", "unset"], "supports": [], "isInherited": true}, "resize": {"subproperties": ["resize"], "values": ["both", "horizontal", "inherit", "initial", "none", "unset", "vertical"], "supports": [], "isInherited": false}, "offset-inline-end": {"subproperties": ["offset-inline-end"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "paint-order": {"subproperties": ["paint-order"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "stroke-linecap": {"subproperties": ["stroke-linecap"], "values": ["butt", "inherit", "initial", "round", "square", "unset"], "supports": [], "isInherited": true}, "animation-direction": {"subproperties": ["animation-direction"], "values": ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset"], "supports": [], "isInherited": false}, "border-top-left-radius": {"subproperties": ["border-top-left-radius"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-box-align": {"subproperties": ["-moz-box-align"], "values": ["baseline", "center", "end", "inherit", "initial", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "-moz-text-size-adjust": {"subproperties": ["-moz-text-size-adjust"], "values": ["auto", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": true}, "list-style": {"subproperties": ["list-style-type", "list-style-image", "list-style-position"], "values": ["inherit", "initial", "inside", "none", "outside", "unset", "url"], "supports": [11], "isInherited": true}, "stroke": {"subproperties": ["stroke"], "values": ["inherit", "initial", "unset"], "supports": [2, 11], "isInherited": true}, "text-decoration-line": {"subproperties": ["text-decoration-line"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-webkit-background-size": {"subproperties": ["background-size"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "padding-bottom": {"subproperties": ["padding-bottom"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-image-slice": {"subproperties": ["border-image-slice"], "values": ["inherit", "initial", "unset"], "supports": [7, 8], "isInherited": false}, "-webkit-transition-delay": {"subproperties": ["transition-delay"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "background-repeat": {"subproperties": ["background-repeat"], "values": ["inherit", "initial", "no-repeat", "repeat", "repeat-x", "repeat-y", "round", "space", "unset"], "supports": [], "isInherited": false}, "flex-basis": {"subproperties": ["flex-basis"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-border-right-colors": {"subproperties": ["-moz-border-right-colors"], "values": ["inherit", "initial", "unset"], "supports": [2], "isInherited": false}, "-moz-image-region": {"subproperties": ["-moz-image-region"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "-webkit-transform-origin": {"subproperties": ["transform-origin"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "vector-effect": {"subproperties": ["vector-effect"], "values": ["inherit", "initial", "non-scaling-stroke", "none", "unset"], "supports": [], "isInherited": false}, "-moz-margin-end": {"subproperties": ["margin-inline-end"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-border-image": {"subproperties": ["border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat"], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "supports": [4, 5, 6, 7, 8, 11], "isInherited": false}, "-moz-border-end-color": {"subproperties": ["border-inline-end-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "ruby-position": {"subproperties": ["ruby-position"], "values": ["inherit", "initial", "over", "under", "unset"], "supports": [], "isInherited": true}, "inline-size": {"subproperties": ["inline-size"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "outline": {"subproperties": ["outline-width", "outline-style", "outline-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "auto", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "text-decoration": {"subproperties": ["text-decoration-color", "text-decoration-line", "text-decoration-style"], "values": ["COLOR", "-moz-none", "-moz-use-text-color", "currentColor", "dashed", "dotted", "double", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "solid", "transparent", "unset", "wavy"], "supports": [2], "isInherited": false}, "transition-duration": {"subproperties": ["transition-duration"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "order": {"subproperties": ["order"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "ime-mode": {"subproperties": ["ime-mode"], "values": ["active", "auto", "disabled", "inactive", "inherit", "initial", "normal", "unset"], "supports": [], "isInherited": false}, "counter-reset": {"subproperties": ["counter-reset"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "flood-opacity": {"subproperties": ["flood-opacity"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "flex-direction": {"subproperties": ["flex-direction"], "values": ["column", "column-reverse", "inherit", "initial", "row", "row-reverse", "unset"], "supports": [], "isInherited": false}, "-webkit-text-stroke-width": {"subproperties": ["-webkit-text-stroke-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": true}, "font-variant-numeric": {"subproperties": ["font-variant-numeric"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "-webkit-flex-wrap": {"subproperties": ["flex-wrap"], "values": ["inherit", "initial", "nowrap", "unset", "wrap", "wrap-reverse"], "supports": [], "isInherited": false}, "min-height": {"subproperties": ["min-height"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "left": {"subproperties": ["left"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-mask": {"subproperties": ["mask-image", "mask-repeat", "mask-position-x", "mask-position-y", "mask-clip", "mask-origin", "mask-size", "mask-composite", "mask-mode"], "supports": [4, 5, 6, 8, 11], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "add", "alpha", "border-box", "content-box", "exclude", "inherit", "initial", "intersect", "linear-gradient", "luminance", "match-source", "no-repeat", "none", "padding-box", "radial-gradient", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "round", "space", "subtract", "unset", "url"], "isInherited": false}, "stroke-width": {"subproperties": ["stroke-width"], "values": ["inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": true}, "-moz-hyphens": {"subproperties": ["hyphens"], "values": ["auto", "inherit", "initial", "manual", "none", "unset"], "supports": [], "isInherited": true}, "background-origin": {"subproperties": ["background-origin"], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "supports": [], "isInherited": false}, "-moz-box-direction": {"subproperties": ["-moz-box-direction"], "values": ["inherit", "initial", "normal", "reverse", "unset"], "supports": [], "isInherited": false}, "border-inline-end-color": {"subproperties": ["border-inline-end-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "marker-offset": {"subproperties": ["marker-offset"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6], "isInherited": false}, "-webkit-background-clip": {"subproperties": ["background-clip"], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "text", "unset"], "supports": [], "isInherited": false}, "border-radius": {"subproperties": ["border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "flex": {"subproperties": ["flex-grow", "flex-shrink", "flex-basis"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": false}, "margin-inline-end": {"subproperties": ["margin-inline-end"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-appearance": {"subproperties": ["-moz-appearance"], "values": ["-moz-gtk-info-bar", "-moz-mac-disclosure-button-closed", "-moz-mac-disclosure-button-open", "-moz-mac-fullscreen-button", "-moz-mac-help-button", "-moz-mac-source-list", "-moz-mac-vibrancy-dark", "-moz-mac-vibrancy-light", "-moz-win-borderless-glass", "-moz-win-browsertabbar-toolbox", "-moz-win-communications-toolbox", "-moz-win-exclude-glass", "-moz-win-glass", "-moz-win-media-toolbox", "-moz-window-button-box", "-moz-window-button-box-maximized", "-moz-window-button-close", "-moz-window-button-maximize", "-moz-window-button-minimize", "-moz-window-button-restore", "-moz-window-frame-bottom", "-moz-window-frame-left", "-moz-window-frame-right", "-moz-window-titlebar", "-moz-window-titlebar-maximized", "button", "button-arrow-down", "button-arrow-next", "button-arrow-previous", "button-arrow-up", "button-bevel", "button-focus", "caret", "checkbox", "checkbox-container", "checkbox-label", "checkmenuitem", "dialog", "dualbutton", "groupbox", "inherit", "initial", "listbox", "listitem", "menuarrow", "menubar", "menucheckbox", "menuimage", "menuitem", "menuitemtext", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menupopup", "menuradio", "menuseparator", "meterbar", "meterchunk", "none", "number-input", "progressbar", "progressbar-vertical", "progresschunk", "progresschunk-vertical", "radio", "radio-container", "radio-label", "radiomenuitem", "range", "range-thumb", "resizer", "resizerpanel", "scale-horizontal", "scale-vertical", "scalethumb-horizontal", "scalethumb-vertical", "scalethumbend", "scalethumbstart", "scalethumbtick", "scrollbar", "scrollbar-horizontal", "scrollbar-small", "scrollbar-vertical", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbarthumb-horizontal", "scrollbarthumb-vertical", "scrollbartrack-horizontal", "scrollbartrack-vertical", "searchfield", "separator", "spinner", "spinner-downbutton", "spinner-textfield", "spinner-upbutton", "splitter", "statusbar", "statusbarpanel", "tab", "tab-scroll-arrow-back", "tab-scroll-arrow-forward", "tabpanel", "tabpanels", "textfield", "textfield-multiline", "toolbar", "toolbarbutton", "toolbarbutton-dropdown", "toolbargripper", "toolbox", "tooltip", "treeheader", "treeheadercell", "treeheadersortarrow", "treeitem", "treeline", "treetwisty", "treetwistyopen", "treeview", "unset", "window"], "supports": [], "isInherited": false}, "box-decoration-break": {"subproperties": ["box-decoration-break"], "values": ["clone", "inherit", "initial", "slice", "unset"], "supports": [], "isInherited": false}, "text-indent": {"subproperties": ["text-indent"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": true}, "hyphens": {"subproperties": ["hyphens"], "values": ["auto", "inherit", "initial", "manual", "none", "unset"], "supports": [], "isInherited": true}, "-moz-perspective": {"subproperties": ["perspective"], "values": ["inherit", "initial", "none", "unset"], "supports": [6], "isInherited": false}, "-webkit-animation-timing-function": {"subproperties": ["animation-timing-function"], "values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "text-transform": {"subproperties": ["text-transform"], "values": ["capitalize", "full-width", "inherit", "initial", "lowercase", "none", "unset", "uppercase"], "supports": [], "isInherited": true}, "font-size": {"subproperties": ["font-size"], "values": ["-moz-calc", "calc", "inherit", "initial", "large", "larger", "medium", "small", "smaller", "unset", "x-large", "x-small", "xx-large", "xx-small"], "supports": [6, 8], "isInherited": true}, "-webkit-animation-name": {"subproperties": ["animation-name"], "values": ["inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "-moz-border-start": {"subproperties": ["border-inline-start-width", "border-inline-start-style", "border-inline-start-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "mask-composite": {"subproperties": ["mask-composite"], "supports": [], "values": ["add", "exclude", "inherit", "initial", "intersect", "subtract", "unset"], "isInherited": false}, "-webkit-text-stroke": {"subproperties": ["-webkit-text-stroke-width", "-webkit-text-stroke-color"], "values": ["COLOR", "-moz-calc", "calc", "currentColor", "hsl", "hsla", "inherit", "initial", "medium", "rgb", "rgba", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": true}, "padding-top": {"subproperties": ["padding-top"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-flex-shrink": {"subproperties": ["flex-shrink"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "color-adjust": {"subproperties": ["color-adjust"], "values": ["economy", "exact", "inherit", "initial", "unset"], "supports": [], "isInherited": true}, "grid-template-rows": {"subproperties": ["grid-template-rows"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "content": {"subproperties": ["content"], "values": ["inherit", "initial", "unset"], "supports": [11], "isInherited": false}, "padding-right": {"subproperties": ["padding-right"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-transform": {"subproperties": ["transform"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "marker-mid": {"subproperties": ["marker-mid"], "values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": true}, "-moz-column-gap": {"subproperties": ["-moz-column-gap"], "values": ["-moz-calc", "calc", "inherit", "initial", "normal", "unset"], "supports": [6], "isInherited": false}, "-moz-border-start-style": {"subproperties": ["border-inline-start-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "clip-rule": {"subproperties": ["clip-rule"], "values": ["evenodd", "inherit", "initial", "nonzero", "unset"], "supports": [], "isInherited": true}, "font-family": {"subproperties": ["font-family"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "block-size": {"subproperties": ["block-size"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "offset-inline-start": {"subproperties": ["offset-inline-start"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "padding-block-end": {"subproperties": ["padding-block-end"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "transition": {"subproperties": ["transition-property", "transition-duration", "transition-timing-function", "transition-delay"], "values": ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset"], "supports": [9, 10], "isInherited": false}, "filter": {"subproperties": ["filter"], "values": ["inherit", "initial", "unset"], "supports": [11], "isInherited": false}, "border-right-width": {"subproperties": ["border-right-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-webkit-flex-direction": {"subproperties": ["flex-direction"], "values": ["column", "column-reverse", "inherit", "initial", "row", "row-reverse", "unset"], "supports": [], "isInherited": false}, "-webkit-mask-composite": {"subproperties": ["mask-composite"], "supports": [], "values": ["add", "exclude", "inherit", "initial", "intersect", "subtract", "unset"], "isInherited": false}, "mix-blend-mode": {"subproperties": ["mix-blend-mode"], "values": ["color", "color-burn", "color-dodge", "darken", "difference", "exclusion", "hard-light", "hue", "inherit", "initial", "lighten", "luminosity", "multiply", "normal", "overlay", "saturation", "screen", "soft-light", "unset"], "supports": [], "isInherited": false}, "color-interpolation": {"subproperties": ["color-interpolation"], "values": ["auto", "inherit", "initial", "linearrgb", "srgb", "unset"], "supports": [], "isInherited": true}, "border-top-style": {"subproperties": ["border-top-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "fill-opacity": {"subproperties": ["fill-opacity"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": true}, "marker-start": {"subproperties": ["marker-start"], "values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": true}, "border-bottom-width": {"subproperties": ["border-bottom-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-moz-column-rule-style": {"subproperties": ["-moz-column-rule-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "clear": {"subproperties": ["clear"], "values": ["both", "inherit", "initial", "inline-end", "inline-start", "left", "none", "right", "unset"], "supports": [], "isInherited": false}, "grid-area": {"subproperties": ["grid-row-start", "grid-column-start", "grid-row-end", "grid-column-end"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "padding-inline-start": {"subproperties": ["padding-inline-start"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-border-end": {"subproperties": ["border-inline-end-width", "border-inline-end-style", "border-inline-end-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "background-clip": {"subproperties": ["background-clip"], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "text", "unset"], "supports": [], "isInherited": false}, "-webkit-text-fill-color": {"subproperties": ["-webkit-text-fill-color"], "values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": true}, "border-block-start-style": {"subproperties": ["border-block-start-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "top": {"subproperties": ["top"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-width": {"subproperties": ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "max-inline-size": {"subproperties": ["max-inline-size"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset"], "supports": [6, 8], "isInherited": false}, "border-inline-start-width": {"subproperties": ["border-inline-start-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-moz-box-flex": {"subproperties": ["-moz-box-flex"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "animation-play-state": {"subproperties": ["animation-play-state"], "values": ["inherit", "initial", "paused", "running", "unset"], "supports": [], "isInherited": false}, "padding": {"subproperties": ["padding-top", "padding-right", "padding-bottom", "padding-left"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "dominant-baseline": {"subproperties": ["dominant-baseline"], "values": ["alphabetic", "auto", "central", "hanging", "ideographic", "inherit", "initial", "mathematical", "middle", "no-change", "reset-size", "text-after-edge", "text-before-edge", "unset", "use-script"], "supports": [], "isInherited": false}, "background-attachment": {"subproperties": ["background-attachment"], "values": ["fixed", "inherit", "initial", "local", "scroll", "unset"], "supports": [], "isInherited": false}, "-webkit-box-sizing": {"subproperties": ["box-sizing"], "values": ["border-box", "content-box", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-webkit-box-flex": {"subproperties": ["-moz-box-flex"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "text-orientation": {"subproperties": ["text-orientation"], "values": ["inherit", "initial", "mixed", "sideways", "sideways-right", "unset", "upright"], "supports": [], "isInherited": true}, "-moz-margin-start": {"subproperties": ["margin-inline-start"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "isolation": {"subproperties": ["isolation"], "values": ["auto", "inherit", "initial", "isolate", "unset"], "supports": [], "isInherited": false}, "-moz-border-bottom-colors": {"subproperties": ["-moz-border-bottom-colors"], "values": ["inherit", "initial", "unset"], "supports": [2], "isInherited": false}, "-moz-column-rule-width": {"subproperties": ["-moz-column-rule-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "scroll-snap-type-y": {"subproperties": ["scroll-snap-type-y"], "values": ["inherit", "initial", "mandatory", "none", "proximity", "unset"], "supports": [], "isInherited": false}, "-webkit-border-bottom-right-radius": {"subproperties": ["border-bottom-right-radius"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-column-count": {"subproperties": ["-moz-column-count"], "values": ["auto", "inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "border-left-width": {"subproperties": ["border-left-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "grid-column-end": {"subproperties": ["grid-column-end"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "background-blend-mode": {"subproperties": ["background-blend-mode"], "values": ["color", "color-burn", "color-dodge", "darken", "difference", "exclusion", "hard-light", "hue", "inherit", "initial", "lighten", "luminosity", "multiply", "normal", "overlay", "saturation", "screen", "soft-light", "unset"], "supports": [], "isInherited": false}, "vertical-align": {"subproperties": ["vertical-align"], "values": ["-moz-calc", "-moz-middle-with-baseline", "baseline", "bottom", "calc", "inherit", "initial", "middle", "sub", "super", "text-bottom", "text-top", "top", "unset"], "supports": [6, 8], "isInherited": false}, "clip": {"subproperties": ["clip"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "grid-auto-rows": {"subproperties": ["grid-auto-rows"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "margin-left": {"subproperties": ["margin-left"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "animation-name": {"subproperties": ["animation-name"], "values": ["inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "border-image-source": {"subproperties": ["border-image-source"], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "supports": [4, 5, 11], "isInherited": false}, "border": {"subproperties": ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width", "border-top-style", "border-right-style", "border-bottom-style", "border-left-style", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "-moz-border-top-colors", "-moz-border-right-colors", "-moz-border-bottom-colors", "-moz-border-left-colors", "border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat"], "values": ["COLOR", "-moz-calc", "-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "linear-gradient", "medium", "none", "outset", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset", "url"], "supports": [2, 6], "isInherited": false}, "-webkit-transition-timing-function": {"subproperties": ["transition-timing-function"], "values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "margin-bottom": {"subproperties": ["margin-bottom"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "animation": {"subproperties": ["animation-duration", "animation-timing-function", "animation-delay", "animation-direction", "animation-fill-mode", "animation-iteration-count", "animation-play-state", "animation-name"], "values": ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset"], "supports": [7, 9, 10], "isInherited": false}, "font-weight": {"subproperties": ["font-weight"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": true}, "border-block-start-width": {"subproperties": ["border-block-start-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "mask-type": {"subproperties": ["mask-type"], "values": ["alpha", "inherit", "initial", "luminance", "unset"], "supports": [], "isInherited": false}, "margin-block-end": {"subproperties": ["margin-block-end"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "min-inline-size": {"subproperties": ["min-inline-size"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "object-position": {"subproperties": ["object-position"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "page-break-after": {"subproperties": ["page-break-after"], "values": ["always", "auto", "avoid", "inherit", "initial", "left", "right", "unset"], "supports": [], "isInherited": false}, "transition-property": {"subproperties": ["transition-property"], "values": ["all", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "-moz-float-edge": {"subproperties": ["-moz-float-edge"], "values": ["content-box", "inherit", "initial", "margin-box", "unset"], "supports": [], "isInherited": false}, "white-space": {"subproperties": ["white-space"], "values": ["-moz-pre-space", "inherit", "initial", "normal", "nowrap", "pre", "pre-line", "pre-wrap", "unset"], "supports": [], "isInherited": true}, "-moz-binding": {"subproperties": ["-moz-binding"], "values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": false}, "ruby-align": {"subproperties": ["ruby-align"], "values": ["center", "inherit", "initial", "space-around", "space-between", "start", "unset"], "supports": [], "isInherited": true}, "font-kerning": {"subproperties": ["font-kerning"], "values": ["auto", "inherit", "initial", "none", "normal", "unset"], "supports": [], "isInherited": true}, "border-block-end": {"subproperties": ["border-block-end-width", "border-block-end-style", "border-block-end-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "animation-timing-function": {"subproperties": ["animation-timing-function"], "values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "-webkit-border-radius": {"subproperties": ["border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "animation-iteration-count": {"subproperties": ["animation-iteration-count"], "values": ["infinite", "inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-webkit-animation-direction": {"subproperties": ["animation-direction"], "values": ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset"], "supports": [], "isInherited": false}, "justify-self": {"subproperties": ["justify-self"], "values": ["auto", "baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "-moz-border-top-colors": {"subproperties": ["-moz-border-top-colors"], "values": ["inherit", "initial", "unset"], "supports": [2], "isInherited": false}, "transition-timing-function": {"subproperties": ["transition-timing-function"], "values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "-moz-transition-duration": {"subproperties": ["transition-duration"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "scroll-snap-coordinate": {"subproperties": ["scroll-snap-coordinate"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-box-orient": {"subproperties": ["-moz-box-orient"], "values": ["block-axis", "horizontal", "inherit", "initial", "inline-axis", "unset", "vertical"], "supports": [], "isInherited": false}, "counter-increment": {"subproperties": ["counter-increment"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-webkit-transform-style": {"subproperties": ["transform-style"], "values": ["flat", "inherit", "initial", "preserve-3d", "unset"], "supports": [], "isInherited": false}, "-moz-transition-timing-function": {"subproperties": ["transition-timing-function"], "values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "grid-auto-columns": {"subproperties": ["grid-auto-columns"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-align-content": {"subproperties": ["align-content"], "values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "space-around", "space-between", "space-evenly", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "font": {"subproperties": ["font-family", "font-style", "font-weight", "font-size", "line-height", "font-size-adjust", "font-stretch", "-x-system-font", "font-feature-settings", "font-language-override", "font-kerning", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position"], "values": ["-moz-block-height", "-moz-calc", "all-petite-caps", "all-small-caps", "auto", "calc", "condensed", "expanded", "extra-condensed", "extra-expanded", "inherit", "initial", "italic", "large", "larger", "medium", "none", "normal", "oblique", "petite-caps", "semi-condensed", "semi-expanded", "small", "small-caps", "smaller", "sub", "super", "titling-caps", "ultra-condensed", "ultra-expanded", "unicase", "unset", "x-large", "x-small", "xx-large", "xx-small"], "supports": [6, 7, 8], "isInherited": true}, "flex-wrap": {"subproperties": ["flex-wrap"], "values": ["inherit", "initial", "nowrap", "unset", "wrap", "wrap-reverse"], "supports": [], "isInherited": false}, "grid-row-start": {"subproperties": ["grid-row-start"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "list-style-image": {"subproperties": ["list-style-image"], "values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": true}, "text-emphasis-position": {"subproperties": ["text-emphasis-position"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "border-right": {"subproperties": ["border-right-width", "border-right-style", "border-right-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "font-style": {"subproperties": ["font-style"], "values": ["inherit", "initial", "italic", "normal", "oblique", "unset"], "supports": [], "isInherited": true}, "box-shadow": {"subproperties": ["box-shadow"], "values": ["inherit", "initial", "unset"], "supports": [2, 6], "isInherited": false}, "align-self": {"subproperties": ["align-self"], "values": ["auto", "baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "text-emphasis-color": {"subproperties": ["text-emphasis-color"], "values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": true}, "border-bottom": {"subproperties": ["border-bottom-width", "border-bottom-style", "border-bottom-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "border-spacing": {"subproperties": ["border-spacing"], "values": ["inherit", "initial", "unset"], "supports": [6], "isInherited": true}, "-webkit-border-top-right-radius": {"subproperties": ["border-top-right-radius"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "margin-inline-start": {"subproperties": ["margin-inline-start"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "grid-row-end": {"subproperties": ["grid-row-end"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "perspective-origin": {"subproperties": ["perspective-origin"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "page-break-inside": {"subproperties": ["page-break-inside"], "values": ["auto", "avoid", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "scroll-behavior": {"subproperties": ["scroll-behavior"], "values": ["auto", "inherit", "initial", "smooth", "unset"], "supports": [], "isInherited": false}, "-moz-backface-visibility": {"subproperties": ["backface-visibility"], "values": ["hidden", "inherit", "initial", "unset", "visible"], "supports": [], "isInherited": false}, "-moz-outline-radius": {"subproperties": ["-moz-outline-radius-topleft", "-moz-outline-radius-topright", "-moz-outline-radius-bottomright", "-moz-outline-radius-bottomleft"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "mask-clip": {"subproperties": ["mask-clip"], "supports": [], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "isInherited": false}, "grid-row": {"subproperties": ["grid-row-start", "grid-row-end"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "border-bottom-right-radius": {"subproperties": ["border-bottom-right-radius"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "line-height": {"subproperties": ["line-height"], "values": ["-moz-block-height", "-moz-calc", "calc", "inherit", "initial", "normal", "unset"], "supports": [6, 7, 8], "isInherited": true}, "stroke-linejoin": {"subproperties": ["stroke-linejoin"], "values": ["bevel", "inherit", "initial", "miter", "round", "unset"], "supports": [], "isInherited": true}, "text-align-last": {"subproperties": ["text-align-last"], "values": ["auto", "center", "end", "inherit", "initial", "justify", "left", "right", "start", "unset"], "supports": [], "isInherited": true}, "word-spacing": {"subproperties": ["word-spacing"], "values": ["-moz-calc", "calc", "inherit", "initial", "normal", "unset"], "supports": [6, 8], "isInherited": true}, "transform-style": {"subproperties": ["transform-style"], "values": ["flat", "inherit", "initial", "preserve-3d", "unset"], "supports": [], "isInherited": false}, "border-bottom-color": {"subproperties": ["border-bottom-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "font-language-override": {"subproperties": ["font-language-override"], "values": ["inherit", "initial", "normal", "unset"], "supports": [], "isInherited": true}, "-moz-outline-radius-topleft": {"subproperties": ["-moz-outline-radius-topleft"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-image": {"subproperties": ["border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat"], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "supports": [4, 5, 6, 7, 8, 11], "isInherited": false}, "caption-side": {"subproperties": ["caption-side"], "values": ["bottom", "bottom-outside", "inherit", "initial", "left", "right", "top", "top-outside", "unset"], "supports": [], "isInherited": true}, "-webkit-mask-position": {"subproperties": ["mask-position-x", "mask-position-y"], "supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "border-inline-end-width": {"subproperties": ["border-inline-end-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-webkit-border-image": {"subproperties": ["border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat"], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "supports": [4, 5, 6, 7, 8, 11], "isInherited": false}, "font-synthesis": {"subproperties": ["font-synthesis"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "grid-template": {"subproperties": ["grid-template-areas", "grid-template-rows", "grid-template-columns"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-mask-repeat": {"subproperties": ["mask-repeat"], "supports": [], "values": ["inherit", "initial", "no-repeat", "repeat", "repeat-x", "repeat-y", "round", "space", "unset"], "isInherited": false}, "-webkit-justify-content": {"subproperties": ["justify-content"], "values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "space-around", "space-between", "space-evenly", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "text-decoration-color": {"subproperties": ["text-decoration-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "color": {"subproperties": ["color"], "values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": true}, "-moz-border-end-width": {"subproperties": ["border-inline-end-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "height": {"subproperties": ["height"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "margin-right": {"subproperties": ["margin-right"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-border-bottom-left-radius": {"subproperties": ["border-bottom-left-radius"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-transform": {"subproperties": ["transform"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "border-bottom-left-radius": {"subproperties": ["border-bottom-left-radius"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "fill-rule": {"subproperties": ["fill-rule"], "values": ["evenodd", "inherit", "initial", "nonzero", "unset"], "supports": [], "isInherited": true}, "min-width": {"subproperties": ["min-width"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "empty-cells": {"subproperties": ["empty-cells"], "values": ["hide", "inherit", "initial", "show", "unset"], "supports": [], "isInherited": true}, "direction": {"subproperties": ["direction"], "values": ["inherit", "initial", "ltr", "rtl", "unset"], "supports": [], "isInherited": true}, "clip-path": {"subproperties": ["clip-path"], "values": ["inherit", "initial", "unset"], "supports": [11], "isInherited": false}, "-webkit-mask-size": {"subproperties": ["mask-size"], "supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "-moz-box-orient": {"subproperties": ["-moz-box-orient"], "values": ["block-axis", "horizontal", "inherit", "initial", "inline-axis", "unset", "vertical"], "supports": [], "isInherited": false}, "z-index": {"subproperties": ["z-index"], "values": ["auto", "inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "background-position-y": {"subproperties": ["background-position-y"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "text-decoration-style": {"subproperties": ["text-decoration-style"], "values": ["-moz-none", "dashed", "dotted", "double", "inherit", "initial", "solid", "unset", "wavy"], "supports": [], "isInherited": false}, "grid-template-areas": {"subproperties": ["grid-template-areas"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-moz-perspective-origin": {"subproperties": ["perspective-origin"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-animation-direction": {"subproperties": ["animation-direction"], "values": ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset"], "supports": [], "isInherited": false}, "font-size-adjust": {"subproperties": ["font-size-adjust"], "values": ["inherit", "initial", "none", "unset"], "supports": [7], "isInherited": true}, "cursor": {"subproperties": ["cursor"], "values": ["inherit", "initial", "unset"], "supports": [11], "isInherited": true}, "margin": {"subproperties": ["margin-top", "margin-right", "margin-bottom", "margin-left"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-animation": {"subproperties": ["animation-duration", "animation-timing-function", "animation-delay", "animation-direction", "animation-fill-mode", "animation-iteration-count", "animation-play-state", "animation-name"], "values": ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset"], "supports": [7, 9, 10], "isInherited": false}, "-moz-control-character-visibility": {"subproperties": ["-moz-control-character-visibility"], "values": ["hidden", "inherit", "initial", "unset", "visible"], "supports": [], "isInherited": true}, "letter-spacing": {"subproperties": ["letter-spacing"], "values": ["-moz-calc", "calc", "inherit", "initial", "normal", "unset"], "supports": [6], "isInherited": true}, "-moz-transition-delay": {"subproperties": ["transition-delay"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "will-change": {"subproperties": ["will-change"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "transform-origin": {"subproperties": ["transform-origin"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "font-variant-ligatures": {"subproperties": ["font-variant-ligatures"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "padding-block-start": {"subproperties": ["padding-block-start"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-animation-duration": {"subproperties": ["animation-duration"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "border-block-end-width": {"subproperties": ["border-block-end-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "-webkit-mask-origin": {"subproperties": ["mask-origin"], "supports": [], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "isInherited": false}, "word-break": {"subproperties": ["word-break"], "values": ["break-all", "inherit", "initial", "keep-all", "normal", "unset"], "supports": [], "isInherited": true}, "table-layout": {"subproperties": ["table-layout"], "values": ["auto", "fixed", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "text-overflow": {"subproperties": ["text-overflow"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-webkit-flex": {"subproperties": ["flex-grow", "flex-shrink", "flex-basis"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": false}, "grid-auto-flow": {"subproperties": ["grid-auto-flow"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "border-top-right-radius": {"subproperties": ["border-top-right-radius"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-image-outset": {"subproperties": ["border-image-outset"], "values": ["inherit", "initial", "unset"], "supports": [6, 7], "isInherited": false}, "mask-size": {"subproperties": ["mask-size"], "supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "touch-action": {"subproperties": ["touch-action"], "values": ["auto", "inherit", "initial", "manipulation", "none", "pan-x", "pan-y", "unset"], "supports": [], "isInherited": false}, "border-right-color": {"subproperties": ["border-right-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "backface-visibility": {"subproperties": ["backface-visibility"], "values": ["hidden", "inherit", "initial", "unset", "visible"], "supports": [], "isInherited": false}, "background-image": {"subproperties": ["background-image"], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "supports": [4, 5, 11], "isInherited": false}, "-moz-box-ordinal-group": {"subproperties": ["-moz-box-ordinal-group"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-webkit-transition-property": {"subproperties": ["transition-property"], "values": ["all", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "writing-mode": {"subproperties": ["writing-mode"], "values": ["horizontal-tb", "inherit", "initial", "lr", "lr-tb", "rl", "rl-tb", "sideways-lr", "sideways-rl", "tb", "tb-rl", "unset", "vertical-lr", "vertical-rl"], "supports": [], "isInherited": true}, "stroke-opacity": {"subproperties": ["stroke-opacity"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": true}, "box-sizing": {"subproperties": ["box-sizing"], "values": ["border-box", "content-box", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "margin-top": {"subproperties": ["margin-top"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "position": {"subproperties": ["position"], "values": ["absolute", "fixed", "inherit", "initial", "relative", "static", "sticky", "unset"], "supports": [], "isInherited": false}, "list-style-position": {"subproperties": ["list-style-position"], "values": ["inherit", "initial", "inside", "outside", "unset"], "supports": [], "isInherited": true}, "-webkit-box-pack": {"subproperties": ["-moz-box-pack"], "values": ["center", "end", "inherit", "initial", "justify", "start", "unset"], "supports": [], "isInherited": false}, "quotes": {"subproperties": ["quotes"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "border-top": {"subproperties": ["border-top-width", "border-top-style", "border-top-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "-moz-animation-delay": {"subproperties": ["animation-delay"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "-webkit-transition": {"subproperties": ["transition-property", "transition-duration", "transition-timing-function", "transition-delay"], "values": ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset"], "supports": [9, 10], "isInherited": false}, "-moz-window-dragging": {"subproperties": ["-moz-window-dragging"], "values": ["default", "drag", "inherit", "initial", "no-drag", "unset"], "supports": [], "isInherited": false}, "lighting-color": {"subproperties": ["lighting-color"], "values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "background-size": {"subproperties": ["background-size"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-border-top-left-radius": {"subproperties": ["border-top-left-radius"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-outline-radius-bottomleft": {"subproperties": ["-moz-outline-radius-bottomleft"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "mask-position-x": {"subproperties": ["mask-position-x"], "supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "mask-position-y": {"subproperties": ["mask-position-y"], "supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "justify-content": {"subproperties": ["justify-content"], "values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "space-around", "space-between", "space-evenly", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "animation-fill-mode": {"subproperties": ["animation-fill-mode"], "values": ["backwards", "both", "forwards", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "-webkit-filter": {"subproperties": ["filter"], "values": ["inherit", "initial", "unset"], "supports": [11], "isInherited": false}, "word-wrap": {"subproperties": ["overflow-wrap"], "values": ["break-word", "inherit", "initial", "normal", "unset"], "supports": [], "isInherited": true}, "grid": {"subproperties": ["grid-template-areas", "grid-template-rows", "grid-template-columns", "grid-auto-flow", "grid-auto-rows", "grid-auto-columns", "grid-row-gap", "grid-column-gap"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "background": {"subproperties": ["background-color", "background-image", "background-repeat", "background-attachment", "background-clip", "background-origin", "background-position-x", "background-position-y", "background-size"], "values": ["COLOR", "-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "border-box", "content-box", "currentColor", "fixed", "hsl", "hsla", "inherit", "initial", "linear-gradient", "local", "no-repeat", "none", "padding-box", "radial-gradient", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "rgb", "rgba", "round", "scroll", "space", "text", "transparent", "unset", "url"], "supports": [2, 4, 5, 6, 8, 11], "isInherited": false}, "margin-block-start": {"subproperties": ["margin-block-start"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "grid-column-start": {"subproperties": ["grid-column-start"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "text-align": {"subproperties": ["text-align"], "values": ["-moz-center", "-moz-left", "-moz-right", "center", "end", "inherit", "initial", "justify", "left", "right", "start", "unset"], "supports": [], "isInherited": true}, "marker-end": {"subproperties": ["marker-end"], "values": ["inherit", "initial", "none", "unset", "url"], "supports": [11], "isInherited": true}, "justify-items": {"subproperties": ["justify-items"], "values": ["auto", "baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "mask-position": {"subproperties": ["mask-position-x", "mask-position-y"], "supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "-moz-columns": {"subproperties": ["-moz-column-count", "-moz-column-width"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 7], "isInherited": false}, "-moz-outline-radius-topright": {"subproperties": ["-moz-outline-radius-topright"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "right": {"subproperties": ["right"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-border-left-colors": {"subproperties": ["-moz-border-left-colors"], "values": ["inherit", "initial", "unset"], "supports": [2], "isInherited": false}, "-webkit-mask-position-x": {"subproperties": ["mask-position-x"], "supports": [6, 8], "values": ["inherit", "initial", "unset"], "isInherited": false}, "-webkit-transition-duration": {"subproperties": ["transition-duration"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "border-top-width": {"subproperties": ["border-top-width"], "values": ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset"], "supports": [6], "isInherited": false}, "bottom": {"subproperties": ["bottom"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-block-end-style": {"subproperties": ["border-block-end-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "-webkit-order": {"subproperties": ["order"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-moz-animation-iteration-count": {"subproperties": ["animation-iteration-count"], "values": ["infinite", "inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-moz-animation-timing-function": {"subproperties": ["animation-timing-function"], "values": ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset"], "supports": [10], "isInherited": false}, "background-color": {"subproperties": ["background-color"], "values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "-webkit-backface-visibility": {"subproperties": ["backface-visibility"], "values": ["hidden", "inherit", "initial", "unset", "visible"], "supports": [], "isInherited": false}, "animation-delay": {"subproperties": ["animation-delay"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "unicode-bidi": {"subproperties": ["unicode-bidi"], "values": ["-moz-isolate", "-moz-isolate-override", "-moz-plaintext", "bidi-override", "embed", "inherit", "initial", "isolate", "isolate-override", "normal", "plaintext", "unset"], "supports": [], "isInherited": false}, "text-shadow": {"subproperties": ["text-shadow"], "values": ["inherit", "initial", "unset"], "supports": [2, 6], "isInherited": true}, "-moz-user-modify": {"subproperties": ["-moz-user-modify"], "values": ["inherit", "initial", "read-only", "read-write", "unset", "write-only"], "supports": [], "isInherited": true}, "-webkit-box-direction": {"subproperties": ["-moz-box-direction"], "values": ["inherit", "initial", "normal", "reverse", "unset"], "supports": [], "isInherited": false}, "image-rendering": {"subproperties": ["image-rendering"], "values": ["-moz-crisp-edges", "auto", "inherit", "initial", "optimizequality", "optimizespeed", "unset"], "supports": [], "isInherited": true}, "border-inline-end": {"subproperties": ["border-inline-end-width", "border-inline-end-style", "border-inline-end-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "grid-gap": {"subproperties": ["grid-row-gap", "grid-column-gap"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-animation-name": {"subproperties": ["animation-name"], "values": ["inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "pointer-events": {"subproperties": ["pointer-events"], "values": ["all", "auto", "fill", "inherit", "initial", "none", "painted", "stroke", "unset", "visible", "visiblefill", "visiblepainted", "visiblestroke"], "supports": [], "isInherited": true}, "border-image-width": {"subproperties": ["border-image-width"], "values": ["inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": false}, "border-inline-start": {"subproperties": ["border-inline-start-width", "border-inline-start-style", "border-inline-start-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "min-block-size": {"subproperties": ["min-block-size"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-mask-clip": {"subproperties": ["mask-clip"], "supports": [], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "isInherited": false}, "-webkit-mask-image": {"subproperties": ["mask-image"], "supports": [4, 5, 11], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url"], "isInherited": false}, "float": {"subproperties": ["float"], "values": ["inherit", "initial", "inline-end", "inline-start", "left", "none", "right", "unset"], "supports": [], "isInherited": false}, "max-height": {"subproperties": ["max-height"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset"], "supports": [6, 8], "isInherited": false}, "outline-offset": {"subproperties": ["outline-offset"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6], "isInherited": false}, "-moz-transform-style": {"subproperties": ["transform-style"], "values": ["flat", "inherit", "initial", "preserve-3d", "unset"], "supports": [], "isInherited": false}, "overflow-wrap": {"subproperties": ["overflow-wrap"], "values": ["break-word", "inherit", "initial", "normal", "unset"], "supports": [], "isInherited": true}, "fill": {"subproperties": ["fill"], "values": ["inherit", "initial", "unset"], "supports": [2, 11], "isInherited": true}, "scroll-snap-type": {"subproperties": ["scroll-snap-type-x", "scroll-snap-type-y"], "values": ["inherit", "initial", "mandatory", "none", "proximity", "unset"], "supports": [], "isInherited": false}, "text-emphasis-style": {"subproperties": ["text-emphasis-style"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": true}, "transform": {"subproperties": ["transform"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-moz-text-align-last": {"subproperties": ["text-align-last"], "values": ["auto", "center", "end", "inherit", "initial", "justify", "left", "right", "start", "unset"], "supports": [], "isInherited": true}, "width": {"subproperties": ["width"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "stroke-miterlimit": {"subproperties": ["stroke-miterlimit"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": true}, "stop-opacity": {"subproperties": ["stop-opacity"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "border-top-color": {"subproperties": ["border-top-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "background-position": {"subproperties": ["background-position-x", "background-position-y"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "scroll-snap-type-x": {"subproperties": ["scroll-snap-type-x"], "values": ["inherit", "initial", "mandatory", "none", "proximity", "unset"], "supports": [], "isInherited": false}, "object-fit": {"subproperties": ["object-fit"], "values": ["contain", "cover", "fill", "inherit", "initial", "none", "scale-down", "unset"], "supports": [], "isInherited": false}, "-moz-box-sizing": {"subproperties": ["box-sizing"], "values": ["border-box", "content-box", "inherit", "initial", "unset"], "supports": [], "isInherited": false}, "offset-block-start": {"subproperties": ["offset-block-start"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-background-origin": {"subproperties": ["background-origin"], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "supports": [], "isInherited": false}, "-webkit-align-items": {"subproperties": ["align-items"], "values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "-moz-padding-start": {"subproperties": ["padding-inline-start"], "values": ["-moz-calc", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "transition-delay": {"subproperties": ["transition-delay"], "values": ["inherit", "initial", "unset"], "supports": [9], "isInherited": false}, "border-style": {"subproperties": ["border-top-style", "border-right-style", "border-bottom-style", "border-left-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "mask-repeat": {"subproperties": ["mask-repeat"], "supports": [], "values": ["inherit", "initial", "no-repeat", "repeat", "repeat-x", "repeat-y", "round", "space", "unset"], "isInherited": false}, "overflow": {"subproperties": ["overflow-x", "overflow-y"], "values": ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible"], "supports": [], "isInherited": false}, "mask-origin": {"subproperties": ["mask-origin"], "supports": [], "values": ["border-box", "content-box", "inherit", "initial", "padding-box", "unset"], "isInherited": false}, "-moz-force-broken-image-icon": {"subproperties": ["-moz-force-broken-image-icon"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "grid-template-columns": {"subproperties": ["grid-template-columns"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-align-self": {"subproperties": ["align-self"], "values": ["auto", "baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "self-end", "self-start", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "-webkit-perspective-origin": {"subproperties": ["perspective-origin"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "border-block-start": {"subproperties": ["border-block-start-width", "border-block-start-style", "border-block-start-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "display": {"subproperties": ["display"], "values": ["-moz-box", "-moz-deck", "-moz-grid", "-moz-grid-group", "-moz-grid-line", "-moz-groupbox", "-moz-inline-box", "-moz-inline-grid", "-moz-inline-stack", "-moz-popup", "-moz-stack", "-webkit-box", "-webkit-flex", "-webkit-inline-box", "-webkit-inline-flex", "block", "contents", "flex", "grid", "inherit", "initial", "inline", "inline-block", "inline-flex", "inline-grid", "inline-table", "list-item", "none", "ruby", "ruby-base", "ruby-base-container", "ruby-text", "ruby-text-container", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "unset"], "supports": [], "isInherited": false}, "-webkit-box-ordinal-group": {"subproperties": ["-moz-box-ordinal-group"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-moz-column-width": {"subproperties": ["-moz-column-width"], "values": ["-moz-calc", "auto", "calc", "inherit", "initial", "unset"], "supports": [6], "isInherited": false}, "border-color": {"subproperties": ["border-top-color", "border-right-color", "border-bottom-color", "border-left-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "-webkit-flex-basis": {"subproperties": ["flex-basis"], "values": ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "stroke-dashoffset": {"subproperties": ["stroke-dashoffset"], "values": ["inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": true}, "-moz-transform-origin": {"subproperties": ["transform-origin"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-webkit-text-size-adjust": {"subproperties": ["-moz-text-size-adjust"], "values": ["auto", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": true}, "border-left-color": {"subproperties": ["border-left-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "overflow-y": {"subproperties": ["overflow-y"], "values": ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible"], "supports": [], "isInherited": false}, "overflow-x": {"subproperties": ["overflow-x"], "values": ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible"], "supports": [], "isInherited": false}, "-moz-user-select": {"subproperties": ["-moz-user-select"], "values": ["-moz-all", "-moz-none", "-moz-text", "all", "auto", "element", "elements", "inherit", "initial", "none", "text", "toggle", "tri-state", "unset"], "supports": [], "isInherited": false}, "-moz-column-rule": {"subproperties": ["-moz-column-rule-width", "-moz-column-rule-style", "-moz-column-rule-color"], "values": ["COLOR", "-moz-calc", "-moz-use-text-color", "calc", "currentColor", "dashed", "dotted", "double", "groove", "hidden", "hsl", "hsla", "inherit", "initial", "inset", "medium", "none", "outset", "rgb", "rgba", "ridge", "solid", "thick", "thin", "transparent", "unset"], "supports": [2, 6], "isInherited": false}, "-moz-outline-radius-bottomright": {"subproperties": ["-moz-outline-radius-bottomright"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "-moz-column-rule-color": {"subproperties": ["-moz-column-rule-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "-moz-transition": {"subproperties": ["transition-property", "transition-duration", "transition-timing-function", "transition-delay"], "values": ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset"], "supports": [9, 10], "isInherited": false}, "opacity": {"subproperties": ["opacity"], "values": ["inherit", "initial", "unset"], "supports": [7], "isInherited": false}, "-webkit-perspective": {"subproperties": ["perspective"], "values": ["inherit", "initial", "none", "unset"], "supports": [6], "isInherited": false}, "-webkit-text-stroke-color": {"subproperties": ["-webkit-text-stroke-color"], "values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": true}, "align-content": {"subproperties": ["align-content"], "values": ["baseline", "center", "end", "flex-end", "flex-start", "inherit", "initial", "last-baseline", "left", "normal", "right", "space-around", "space-between", "space-evenly", "start", "stretch", "unset"], "supports": [], "isInherited": false}, "scroll-snap-points-y": {"subproperties": ["scroll-snap-points-y"], "values": ["inherit", "initial", "unset"], "supports": [], "isInherited": false}, "-moz-transition-property": {"subproperties": ["transition-property"], "values": ["all", "inherit", "initial", "none", "unset"], "supports": [], "isInherited": false}, "border-bottom-style": {"subproperties": ["border-bottom-style"], "values": ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset"], "supports": [], "isInherited": false}, "-moz-animation-play-state": {"subproperties": ["animation-play-state"], "values": ["inherit", "initial", "paused", "running", "unset"], "supports": [], "isInherited": false}, "mask": {"subproperties": ["mask-image", "mask-repeat", "mask-position-x", "mask-position-y", "mask-clip", "mask-origin", "mask-size", "mask-composite", "mask-mode"], "values": ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "add", "alpha", "border-box", "content-box", "exclude", "inherit", "initial", "intersect", "linear-gradient", "luminance", "match-source", "no-repeat", "none", "padding-box", "radial-gradient", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "round", "space", "subtract", "unset", "url"], "supports": [4, 5, 6, 8, 11], "isInherited": false}, "background-position-x": {"subproperties": ["background-position-x"], "values": ["inherit", "initial", "unset"], "supports": [6, 8], "isInherited": false}, "stop-color": {"subproperties": ["stop-color"], "values": ["COLOR", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "border-block-end-color": {"subproperties": ["border-block-end-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}, "stroke-dasharray": {"subproperties": ["stroke-dasharray"], "values": ["inherit", "initial", "unset"], "supports": [6, 7, 8], "isInherited": true}, "border-inline-start-color": {"subproperties": ["border-inline-start-color"], "values": ["COLOR", "-moz-use-text-color", "currentColor", "hsl", "hsla", "inherit", "initial", "rgb", "rgba", "transparent", "unset"], "supports": [2], "isInherited": false}};
 
 /**
  * A list of the pseudo elements.
  */
 exports.PSEUDO_ELEMENTS = [":after", ":before", ":backdrop", ":first-letter", ":first-line", ":-moz-selection", ":-moz-focus-inner", ":-moz-focus-outer", ":-moz-list-bullet", ":-moz-list-number", ":-moz-math-anonymous", ":-moz-progress-bar", ":-moz-range-track", ":-moz-range-progress", ":-moz-range-thumb", ":-moz-meter-bar", ":-moz-placeholder", ":placeholder", ":-moz-color-swatch"];
 
 /**
  * A list of the preferences keys for whether a CSS property is enabled or not. This is
  * exposed for testing purposes.
  */
-exports.PREFERENCES = [["align-content", ""], ["align-items", ""], ["align-self", ""], ["all", "layout.css.all-shorthand.enabled"], ["animation", ""], ["animation-delay", ""], ["animation-direction", ""], ["animation-duration", ""], ["animation-fill-mode", ""], ["animation-iteration-count", ""], ["animation-name", ""], ["animation-play-state", ""], ["animation-timing-function", ""], ["-moz-appearance", ""], ["backface-visibility", ""], ["background", ""], ["background-attachment", ""], ["background-blend-mode", "layout.css.background-blend-mode.enabled"], ["background-clip", ""], ["background-color", ""], ["background-image", ""], ["background-origin", ""], ["background-position", ""], ["background-position-x", ""], ["background-position-y", ""], ["background-repeat", ""], ["background-size", ""], ["-moz-binding", ""], ["block-size", "layout.css.vertical-text.enabled"], ["border", ""], ["border-block-end", "layout.css.vertical-text.enabled"], ["border-block-end-color", "layout.css.vertical-text.enabled"], ["border-block-end-style", "layout.css.vertical-text.enabled"], ["border-block-end-width", "layout.css.vertical-text.enabled"], ["border-block-start", "layout.css.vertical-text.enabled"], ["border-block-start-color", "layout.css.vertical-text.enabled"], ["border-block-start-style", "layout.css.vertical-text.enabled"], ["border-block-start-width", "layout.css.vertical-text.enabled"], ["border-bottom", ""], ["border-bottom-color", ""], ["-moz-border-bottom-colors", ""], ["border-bottom-left-radius", ""], ["border-bottom-right-radius", ""], ["border-bottom-style", ""], ["border-bottom-width", ""], ["border-collapse", ""], ["border-color", ""], ["border-image", ""], ["border-image-outset", ""], ["border-image-repeat", ""], ["border-image-slice", ""], ["border-image-source", ""], ["border-image-width", ""], ["border-inline-end", ""], ["border-inline-end-color", ""], ["border-inline-end-style", ""], ["border-inline-end-width", ""], ["border-inline-start", ""], ["border-inline-start-color", ""], ["border-inline-start-style", ""], ["border-inline-start-width", ""], ["border-left", ""], ["border-left-color", ""], ["-moz-border-left-colors", ""], ["border-left-style", ""], ["border-left-width", ""], ["border-radius", ""], ["border-right", ""], ["border-right-color", ""], ["-moz-border-right-colors", ""], ["border-right-style", ""], ["border-right-width", ""], ["border-spacing", ""], ["border-style", ""], ["border-top", ""], ["border-top-color", ""], ["-moz-border-top-colors", ""], ["border-top-left-radius", ""], ["border-top-right-radius", ""], ["border-top-style", ""], ["border-top-width", ""], ["border-width", ""], ["bottom", ""], ["-moz-box-align", ""], ["box-decoration-break", "layout.css.box-decoration-break.enabled"], ["-moz-box-direction", ""], ["-moz-box-flex", ""], ["-moz-box-ordinal-group", ""], ["-moz-box-orient", ""], ["-moz-box-pack", ""], ["box-shadow", ""], ["box-sizing", ""], ["caption-side", ""], ["clear", ""], ["clip", ""], ["clip-path", ""], ["clip-rule", ""], ["color", ""], ["color-adjust", "layout.css.color-adjust.enabled"], ["color-interpolation", ""], ["color-interpolation-filters", ""], ["-moz-column-count", ""], ["-moz-column-fill", ""], ["-moz-column-gap", ""], ["-moz-column-rule", ""], ["-moz-column-rule-color", ""], ["-moz-column-rule-style", ""], ["-moz-column-rule-width", ""], ["-moz-column-width", ""], ["-moz-columns", ""], ["contain", "layout.css.contain.enabled"], ["content", ""], ["counter-increment", ""], ["counter-reset", ""], ["cursor", ""], ["direction", ""], ["display", ""], ["dominant-baseline", ""], ["empty-cells", ""], ["fill", ""], ["fill-opacity", ""], ["fill-rule", ""], ["filter", ""], ["flex", ""], ["flex-basis", ""], ["flex-direction", ""], ["flex-flow", ""], ["flex-grow", ""], ["flex-shrink", ""], ["flex-wrap", ""], ["float", ""], ["-moz-float-edge", ""], ["flood-color", ""], ["flood-opacity", ""], ["font", ""], ["font-family", ""], ["font-feature-settings", ""], ["font-kerning", ""], ["font-language-override", ""], ["font-size", ""], ["font-size-adjust", ""], ["font-stretch", ""], ["font-style", ""], ["font-synthesis", ""], ["font-variant", ""], ["font-variant-alternates", ""], ["font-variant-caps", ""], ["font-variant-east-asian", ""], ["font-variant-ligatures", ""], ["font-variant-numeric", ""], ["font-variant-position", ""], ["font-weight", ""], ["-moz-force-broken-image-icon", ""], ["grid", "layout.css.grid.enabled"], ["grid-area", "layout.css.grid.enabled"], ["grid-auto-columns", "layout.css.grid.enabled"], ["grid-auto-flow", "layout.css.grid.enabled"], ["grid-auto-rows", "layout.css.grid.enabled"], ["grid-column", "layout.css.grid.enabled"], ["grid-column-end", "layout.css.grid.enabled"], ["grid-column-gap", "layout.css.grid.enabled"], ["grid-column-start", "layout.css.grid.enabled"], ["grid-gap", "layout.css.grid.enabled"], ["grid-row", "layout.css.grid.enabled"], ["grid-row-end", "layout.css.grid.enabled"], ["grid-row-gap", "layout.css.grid.enabled"], ["grid-row-start", "layout.css.grid.enabled"], ["grid-template", "layout.css.grid.enabled"], ["grid-template-areas", "layout.css.grid.enabled"], ["grid-template-columns", "layout.css.grid.enabled"], ["grid-template-rows", "layout.css.grid.enabled"], ["height", ""], ["hyphens", ""], ["initial-letter", "layout.css.initial-letter.enabled"], ["image-orientation", "layout.css.image-orientation.enabled"], ["-moz-image-region", ""], ["image-rendering", ""], ["ime-mode", ""], ["inline-size", "layout.css.vertical-text.enabled"], ["isolation", "layout.css.isolation.enabled"], ["justify-content", ""], ["justify-items", ""], ["justify-self", ""], ["left", ""], ["letter-spacing", ""], ["lighting-color", ""], ["line-height", ""], ["list-style", ""], ["list-style-image", ""], ["list-style-position", ""], ["list-style-type", ""], ["margin", ""], ["margin-block-end", "layout.css.vertical-text.enabled"], ["margin-block-start", "layout.css.vertical-text.enabled"], ["margin-bottom", ""], ["margin-inline-end", ""], ["margin-inline-start", ""], ["margin-left", ""], ["margin-right", ""], ["margin-top", ""], ["marker", ""], ["marker-end", ""], ["marker-mid", ""], ["marker-offset", ""], ["marker-start", ""], ["mask", ""], ["mask-clip", ""], ["mask-composite", ""], ["mask-image", ""], ["mask-mode", ""], ["mask-origin", ""], ["mask-position", ""], ["mask-position-x", ""], ["mask-position-y", ""], ["mask-repeat", ""], ["mask-size", ""], ["mask-type", "layout.css.masking.enabled"], ["max-block-size", "layout.css.vertical-text.enabled"], ["max-height", ""], ["max-inline-size", "layout.css.vertical-text.enabled"], ["max-width", ""], ["min-block-size", "layout.css.vertical-text.enabled"], ["min-height", ""], ["min-inline-size", "layout.css.vertical-text.enabled"], ["min-width", ""], ["mix-blend-mode", "layout.css.mix-blend-mode.enabled"], ["object-fit", "layout.css.object-fit-and-position.enabled"], ["object-position", "layout.css.object-fit-and-position.enabled"], ["offset-block-end", "layout.css.vertical-text.enabled"], ["offset-block-start", "layout.css.vertical-text.enabled"], ["offset-inline-end", "layout.css.vertical-text.enabled"], ["offset-inline-start", "layout.css.vertical-text.enabled"], ["opacity", ""], ["order", ""], ["-moz-orient", ""], ["-moz-osx-font-smoothing", "layout.css.osx-font-smoothing.enabled"], ["outline", ""], ["outline-color", ""], ["outline-offset", ""], ["-moz-outline-radius", ""], ["-moz-outline-radius-bottomleft", ""], ["-moz-outline-radius-bottomright", ""], ["-moz-outline-radius-topleft", ""], ["-moz-outline-radius-topright", ""], ["outline-style", ""], ["outline-width", ""], ["overflow", ""], ["overflow-clip-box", "layout.css.overflow-clip-box.enabled"], ["overflow-x", ""], ["overflow-y", ""], ["padding", ""], ["padding-block-end", "layout.css.vertical-text.enabled"], ["padding-block-start", "layout.css.vertical-text.enabled"], ["padding-bottom", ""], ["padding-inline-end", ""], ["padding-inline-start", ""], ["padding-left", ""], ["padding-right", ""], ["padding-top", ""], ["page-break-after", ""], ["page-break-before", ""], ["page-break-inside", ""], ["paint-order", "svg.paint-order.enabled"], ["perspective", ""], ["perspective-origin", ""], ["pointer-events", ""], ["position", ""], ["quotes", ""], ["resize", ""], ["right", ""], ["ruby-align", ""], ["ruby-position", ""], ["scroll-behavior", "layout.css.scroll-behavior.property-enabled"], ["scroll-snap-coordinate", "layout.css.scroll-snap.enabled"], ["scroll-snap-destination", "layout.css.scroll-snap.enabled"], ["scroll-snap-points-x", "layout.css.scroll-snap.enabled"], ["scroll-snap-points-y", "layout.css.scroll-snap.enabled"], ["scroll-snap-type", "layout.css.scroll-snap.enabled"], ["scroll-snap-type-x", "layout.css.scroll-snap.enabled"], ["scroll-snap-type-y", "layout.css.scroll-snap.enabled"], ["shape-outside", "layout.css.shape-outside.enabled"], ["shape-rendering", ""], ["-moz-stack-sizing", ""], ["stop-color", ""], ["stop-opacity", ""], ["stroke", ""], ["stroke-dasharray", ""], ["stroke-dashoffset", ""], ["stroke-linecap", ""], ["stroke-linejoin", ""], ["stroke-miterlimit", ""], ["stroke-opacity", ""], ["stroke-width", ""], ["-moz-tab-size", ""], ["table-layout", ""], ["text-align", ""], ["text-align-last", ""], ["text-anchor", ""], ["text-combine-upright", "layout.css.text-combine-upright.enabled"], ["text-decoration", ""], ["text-decoration-color", ""], ["text-decoration-line", ""], ["text-decoration-style", ""], ["text-emphasis", ""], ["text-emphasis-color", ""], ["text-emphasis-position", ""], ["text-emphasis-style", ""], ["-webkit-text-fill-color", "layout.css.prefixes.webkit"], ["text-indent", ""], ["text-orientation", "layout.css.vertical-text.enabled"], ["text-overflow", ""], ["text-rendering", ""], ["text-shadow", ""], ["-moz-text-size-adjust", ""], ["-webkit-text-stroke", "layout.css.prefixes.webkit"], ["-webkit-text-stroke-color", "layout.css.prefixes.webkit"], ["-webkit-text-stroke-width", "layout.css.prefixes.webkit"], ["text-transform", ""], ["top", ""], ["touch-action", "layout.css.touch_action.enabled"], ["transform", ""], ["-moz-transform", "layout.css.prefixes.transforms"], ["transform-box", "svg.transform-box.enabled"], ["transform-origin", ""], ["transform-style", ""], ["transition", ""], ["transition-delay", ""], ["transition-duration", ""], ["transition-property", ""], ["transition-timing-function", ""], ["unicode-bidi", ""], ["-moz-user-focus", ""], ["-moz-user-input", ""], ["-moz-user-modify", ""], ["-moz-user-select", ""], ["vector-effect", ""], ["vertical-align", ""], ["visibility", ""], ["white-space", ""], ["width", ""], ["will-change", ""], ["-moz-window-dragging", ""], ["word-break", ""], ["word-spacing", ""], ["overflow-wrap", ""], ["writing-mode", "layout.css.vertical-text.enabled"], ["z-index", ""], ["word-wrap", ""], ["-moz-transform-origin", "layout.css.prefixes.transforms"], ["-moz-perspective-origin", "layout.css.prefixes.transforms"], ["-moz-perspective", "layout.css.prefixes.transforms"], ["-moz-transform-style", "layout.css.prefixes.transforms"], ["-moz-backface-visibility", "layout.css.prefixes.transforms"], ["-moz-border-image", "layout.css.prefixes.border-image"], ["-moz-transition", "layout.css.prefixes.transitions"], ["-moz-transition-delay", "layout.css.prefixes.transitions"], ["-moz-transition-duration", "layout.css.prefixes.transitions"], ["-moz-transition-property", "layout.css.prefixes.transitions"], ["-moz-transition-timing-function", "layout.css.prefixes.transitions"], ["-moz-animation", "layout.css.prefixes.animations"], ["-moz-animation-delay", "layout.css.prefixes.animations"], ["-moz-animation-direction", "layout.css.prefixes.animations"], ["-moz-animation-duration", "layout.css.prefixes.animations"], ["-moz-animation-fill-mode", "layout.css.prefixes.animations"], ["-moz-animation-iteration-count", "layout.css.prefixes.animations"], ["-moz-animation-name", "layout.css.prefixes.animations"], ["-moz-animation-play-state", "layout.css.prefixes.animations"], ["-moz-animation-timing-function", "layout.css.prefixes.animations"], ["-moz-box-sizing", "layout.css.prefixes.box-sizing"], ["-moz-font-feature-settings", "layout.css.prefixes.font-features"], ["-moz-font-language-override", "layout.css.prefixes.font-features"], ["-moz-padding-end", ""], ["-moz-padding-start", ""], ["-moz-margin-end", ""], ["-moz-margin-start", ""], ["-moz-border-end", ""], ["-moz-border-end-color", ""], ["-moz-border-end-style", ""], ["-moz-border-end-width", ""], ["-moz-border-start", ""], ["-moz-border-start-color", ""], ["-moz-border-start-style", ""], ["-moz-border-start-width", ""], ["-moz-hyphens", ""], ["-moz-text-align-last", ""], ["-webkit-animation", "layout.css.prefixes.webkit"], ["-webkit-animation-delay", "layout.css.prefixes.webkit"], ["-webkit-animation-direction", "layout.css.prefixes.webkit"], ["-webkit-animation-duration", "layout.css.prefixes.webkit"], ["-webkit-animation-fill-mode", "layout.css.prefixes.webkit"], ["-webkit-animation-iteration-count", "layout.css.prefixes.webkit"], ["-webkit-animation-name", "layout.css.prefixes.webkit"], ["-webkit-animation-play-state", "layout.css.prefixes.webkit"], ["-webkit-animation-timing-function", "layout.css.prefixes.webkit"], ["-webkit-filter", "layout.css.prefixes.webkit"], ["-webkit-text-size-adjust", "layout.css.prefixes.webkit"], ["-webkit-transform", "layout.css.prefixes.webkit"], ["-webkit-transform-origin", "layout.css.prefixes.webkit"], ["-webkit-transform-style", "layout.css.prefixes.webkit"], ["-webkit-backface-visibility", "layout.css.prefixes.webkit"], ["-webkit-perspective", "layout.css.prefixes.webkit"], ["-webkit-perspective-origin", "layout.css.prefixes.webkit"], ["-webkit-transition", "layout.css.prefixes.webkit"], ["-webkit-transition-delay", "layout.css.prefixes.webkit"], ["-webkit-transition-duration", "layout.css.prefixes.webkit"], ["-webkit-transition-property", "layout.css.prefixes.webkit"], ["-webkit-transition-timing-function", "layout.css.prefixes.webkit"], ["-webkit-border-radius", "layout.css.prefixes.webkit"], ["-webkit-border-top-left-radius", "layout.css.prefixes.webkit"], ["-webkit-border-top-right-radius", "layout.css.prefixes.webkit"], ["-webkit-border-bottom-left-radius", "layout.css.prefixes.webkit"], ["-webkit-border-bottom-right-radius", "layout.css.prefixes.webkit"], ["-webkit-background-clip", "layout.css.prefixes.webkit"], ["-webkit-background-origin", "layout.css.prefixes.webkit"], ["-webkit-background-size", "layout.css.prefixes.webkit"], ["-webkit-border-image", "layout.css.prefixes.webkit"], ["-webkit-box-shadow", "layout.css.prefixes.webkit"], ["-webkit-box-sizing", "layout.css.prefixes.webkit"], ["-webkit-box-flex", "layout.css.prefixes.webkit"], ["-webkit-box-ordinal-group", "layout.css.prefixes.webkit"], ["-webkit-box-orient", "layout.css.prefixes.webkit"], ["-webkit-box-direction", "layout.css.prefixes.webkit"], ["-webkit-box-align", "layout.css.prefixes.webkit"], ["-webkit-box-pack", "layout.css.prefixes.webkit"], ["-webkit-flex-direction", "layout.css.prefixes.webkit"], ["-webkit-flex-wrap", "layout.css.prefixes.webkit"], ["-webkit-flex-flow", "layout.css.prefixes.webkit"], ["-webkit-order", "layout.css.prefixes.webkit"], ["-webkit-flex", "layout.css.prefixes.webkit"], ["-webkit-flex-grow", "layout.css.prefixes.webkit"], ["-webkit-flex-shrink", "layout.css.prefixes.webkit"], ["-webkit-flex-basis", "layout.css.prefixes.webkit"], ["-webkit-justify-content", "layout.css.prefixes.webkit"], ["-webkit-align-items", "layout.css.prefixes.webkit"], ["-webkit-align-self", "layout.css.prefixes.webkit"], ["-webkit-align-content", "layout.css.prefixes.webkit"], ["-webkit-user-select", "layout.css.prefixes.webkit"], ["-webkit-mask", "layout.css.prefixes.webkit"], ["-webkit-mask-clip", "layout.css.prefixes.webkit"], ["-webkit-mask-composite", "layout.css.prefixes.webkit"], ["-webkit-mask-image", "layout.css.prefixes.webkit"], ["-webkit-mask-origin", "layout.css.prefixes.webkit"], ["-webkit-mask-position", "layout.css.prefixes.webkit"], ["-webkit-mask-position-x", "layout.css.prefixes.webkit"], ["-webkit-mask-position-y", "layout.css.prefixes.webkit"], ["-webkit-mask-repeat", "layout.css.prefixes.webkit"], ["-webkit-mask-size", "layout.css.prefixes.webkit"]];
+exports.PREFERENCES = [["align-content", ""], ["align-items", ""], ["align-self", ""], ["all", "layout.css.all-shorthand.enabled"], ["animation", ""], ["animation-delay", ""], ["animation-direction", ""], ["animation-duration", ""], ["animation-fill-mode", ""], ["animation-iteration-count", ""], ["animation-name", ""], ["animation-play-state", ""], ["animation-timing-function", ""], ["-moz-appearance", ""], ["backface-visibility", ""], ["background", ""], ["background-attachment", ""], ["background-blend-mode", "layout.css.background-blend-mode.enabled"], ["background-clip", ""], ["background-color", ""], ["background-image", ""], ["background-origin", ""], ["background-position", ""], ["background-position-x", ""], ["background-position-y", ""], ["background-repeat", ""], ["background-size", ""], ["-moz-binding", ""], ["block-size", ""], ["border", ""], ["border-block-end", ""], ["border-block-end-color", ""], ["border-block-end-style", ""], ["border-block-end-width", ""], ["border-block-start", ""], ["border-block-start-color", ""], ["border-block-start-style", ""], ["border-block-start-width", ""], ["border-bottom", ""], ["border-bottom-color", ""], ["-moz-border-bottom-colors", ""], ["border-bottom-left-radius", ""], ["border-bottom-right-radius", ""], ["border-bottom-style", ""], ["border-bottom-width", ""], ["border-collapse", ""], ["border-color", ""], ["border-image", ""], ["border-image-outset", ""], ["border-image-repeat", ""], ["border-image-slice", ""], ["border-image-source", ""], ["border-image-width", ""], ["border-inline-end", ""], ["border-inline-end-color", ""], ["border-inline-end-style", ""], ["border-inline-end-width", ""], ["border-inline-start", ""], ["border-inline-start-color", ""], ["border-inline-start-style", ""], ["border-inline-start-width", ""], ["border-left", ""], ["border-left-color", ""], ["-moz-border-left-colors", ""], ["border-left-style", ""], ["border-left-width", ""], ["border-radius", ""], ["border-right", ""], ["border-right-color", ""], ["-moz-border-right-colors", ""], ["border-right-style", ""], ["border-right-width", ""], ["border-spacing", ""], ["border-style", ""], ["border-top", ""], ["border-top-color", ""], ["-moz-border-top-colors", ""], ["border-top-left-radius", ""], ["border-top-right-radius", ""], ["border-top-style", ""], ["border-top-width", ""], ["border-width", ""], ["bottom", ""], ["-moz-box-align", ""], ["box-decoration-break", "layout.css.box-decoration-break.enabled"], ["-moz-box-direction", ""], ["-moz-box-flex", ""], ["-moz-box-ordinal-group", ""], ["-moz-box-orient", ""], ["-moz-box-pack", ""], ["box-shadow", ""], ["box-sizing", ""], ["caption-side", ""], ["clear", ""], ["clip", ""], ["clip-path", ""], ["clip-rule", ""], ["color", ""], ["color-adjust", "layout.css.color-adjust.enabled"], ["color-interpolation", ""], ["color-interpolation-filters", ""], ["-moz-column-count", ""], ["-moz-column-fill", ""], ["-moz-column-gap", ""], ["-moz-column-rule", ""], ["-moz-column-rule-color", ""], ["-moz-column-rule-style", ""], ["-moz-column-rule-width", ""], ["-moz-column-width", ""], ["-moz-columns", ""], ["contain", "layout.css.contain.enabled"], ["content", ""], ["counter-increment", ""], ["counter-reset", ""], ["cursor", ""], ["direction", ""], ["display", ""], ["dominant-baseline", ""], ["empty-cells", ""], ["fill", ""], ["fill-opacity", ""], ["fill-rule", ""], ["filter", ""], ["flex", ""], ["flex-basis", ""], ["flex-direction", ""], ["flex-flow", ""], ["flex-grow", ""], ["flex-shrink", ""], ["flex-wrap", ""], ["float", ""], ["-moz-float-edge", ""], ["flood-color", ""], ["flood-opacity", ""], ["font", ""], ["font-family", ""], ["font-feature-settings", ""], ["font-kerning", ""], ["font-language-override", ""], ["font-size", ""], ["font-size-adjust", ""], ["font-stretch", ""], ["font-style", ""], ["font-synthesis", ""], ["font-variant", ""], ["font-variant-alternates", ""], ["font-variant-caps", ""], ["font-variant-east-asian", ""], ["font-variant-ligatures", ""], ["font-variant-numeric", ""], ["font-variant-position", ""], ["font-weight", ""], ["-moz-force-broken-image-icon", ""], ["grid", "layout.css.grid.enabled"], ["grid-area", "layout.css.grid.enabled"], ["grid-auto-columns", "layout.css.grid.enabled"], ["grid-auto-flow", "layout.css.grid.enabled"], ["grid-auto-rows", "layout.css.grid.enabled"], ["grid-column", "layout.css.grid.enabled"], ["grid-column-end", "layout.css.grid.enabled"], ["grid-column-gap", "layout.css.grid.enabled"], ["grid-column-start", "layout.css.grid.enabled"], ["grid-gap", "layout.css.grid.enabled"], ["grid-row", "layout.css.grid.enabled"], ["grid-row-end", "layout.css.grid.enabled"], ["grid-row-gap", "layout.css.grid.enabled"], ["grid-row-start", "layout.css.grid.enabled"], ["grid-template", "layout.css.grid.enabled"], ["grid-template-areas", "layout.css.grid.enabled"], ["grid-template-columns", "layout.css.grid.enabled"], ["grid-template-rows", "layout.css.grid.enabled"], ["height", ""], ["hyphens", ""], ["initial-letter", "layout.css.initial-letter.enabled"], ["image-orientation", "layout.css.image-orientation.enabled"], ["-moz-image-region", ""], ["image-rendering", ""], ["ime-mode", ""], ["inline-size", ""], ["isolation", "layout.css.isolation.enabled"], ["justify-content", ""], ["justify-items", ""], ["justify-self", ""], ["left", ""], ["letter-spacing", ""], ["lighting-color", ""], ["line-height", ""], ["list-style", ""], ["list-style-image", ""], ["list-style-position", ""], ["list-style-type", ""], ["margin", ""], ["margin-block-end", ""], ["margin-block-start", ""], ["margin-bottom", ""], ["margin-inline-end", ""], ["margin-inline-start", ""], ["margin-left", ""], ["margin-right", ""], ["margin-top", ""], ["marker", ""], ["marker-end", ""], ["marker-mid", ""], ["marker-offset", ""], ["marker-start", ""], ["mask", ""], ["mask-clip", ""], ["mask-composite", ""], ["mask-image", ""], ["mask-mode", ""], ["mask-origin", ""], ["mask-position", ""], ["mask-position-x", ""], ["mask-position-y", ""], ["mask-repeat", ""], ["mask-size", ""], ["mask-type", "layout.css.masking.enabled"], ["max-block-size", ""], ["max-height", ""], ["max-inline-size", ""], ["max-width", ""], ["min-block-size", ""], ["min-height", ""], ["min-inline-size", ""], ["min-width", ""], ["mix-blend-mode", "layout.css.mix-blend-mode.enabled"], ["object-fit", "layout.css.object-fit-and-position.enabled"], ["object-position", "layout.css.object-fit-and-position.enabled"], ["offset-block-end", ""], ["offset-block-start", ""], ["offset-inline-end", ""], ["offset-inline-start", ""], ["opacity", ""], ["order", ""], ["-moz-orient", ""], ["-moz-osx-font-smoothing", "layout.css.osx-font-smoothing.enabled"], ["outline", ""], ["outline-color", ""], ["outline-offset", ""], ["-moz-outline-radius", ""], ["-moz-outline-radius-bottomleft", ""], ["-moz-outline-radius-bottomright", ""], ["-moz-outline-radius-topleft", ""], ["-moz-outline-radius-topright", ""], ["outline-style", ""], ["outline-width", ""], ["overflow", ""], ["overflow-clip-box", "layout.css.overflow-clip-box.enabled"], ["overflow-x", ""], ["overflow-y", ""], ["padding", ""], ["padding-block-end", ""], ["padding-block-start", ""], ["padding-bottom", ""], ["padding-inline-end", ""], ["padding-inline-start", ""], ["padding-left", ""], ["padding-right", ""], ["padding-top", ""], ["page-break-after", ""], ["page-break-before", ""], ["page-break-inside", ""], ["paint-order", "svg.paint-order.enabled"], ["perspective", ""], ["perspective-origin", ""], ["pointer-events", ""], ["position", ""], ["quotes", ""], ["resize", ""], ["right", ""], ["ruby-align", ""], ["ruby-position", ""], ["scroll-behavior", "layout.css.scroll-behavior.property-enabled"], ["scroll-snap-coordinate", "layout.css.scroll-snap.enabled"], ["scroll-snap-destination", "layout.css.scroll-snap.enabled"], ["scroll-snap-points-x", "layout.css.scroll-snap.enabled"], ["scroll-snap-points-y", "layout.css.scroll-snap.enabled"], ["scroll-snap-type", "layout.css.scroll-snap.enabled"], ["scroll-snap-type-x", "layout.css.scroll-snap.enabled"], ["scroll-snap-type-y", "layout.css.scroll-snap.enabled"], ["shape-outside", "layout.css.shape-outside.enabled"], ["shape-rendering", ""], ["-moz-stack-sizing", ""], ["stop-color", ""], ["stop-opacity", ""], ["stroke", ""], ["stroke-dasharray", ""], ["stroke-dashoffset", ""], ["stroke-linecap", ""], ["stroke-linejoin", ""], ["stroke-miterlimit", ""], ["stroke-opacity", ""], ["stroke-width", ""], ["-moz-tab-size", ""], ["table-layout", ""], ["text-align", ""], ["text-align-last", ""], ["text-anchor", ""], ["text-combine-upright", "layout.css.text-combine-upright.enabled"], ["text-decoration", ""], ["text-decoration-color", ""], ["text-decoration-line", ""], ["text-decoration-style", ""], ["text-emphasis", ""], ["text-emphasis-color", ""], ["text-emphasis-position", ""], ["text-emphasis-style", ""], ["-webkit-text-fill-color", "layout.css.prefixes.webkit"], ["text-indent", ""], ["text-orientation", ""], ["text-overflow", ""], ["text-rendering", ""], ["text-shadow", ""], ["-moz-text-size-adjust", ""], ["-webkit-text-stroke", "layout.css.prefixes.webkit"], ["-webkit-text-stroke-color", "layout.css.prefixes.webkit"], ["-webkit-text-stroke-width", "layout.css.prefixes.webkit"], ["text-transform", ""], ["top", ""], ["touch-action", "layout.css.touch_action.enabled"], ["transform", ""], ["-moz-transform", "layout.css.prefixes.transforms"], ["transform-box", "svg.transform-box.enabled"], ["transform-origin", ""], ["transform-style", ""], ["transition", ""], ["transition-delay", ""], ["transition-duration", ""], ["transition-property", ""], ["transition-timing-function", ""], ["unicode-bidi", ""], ["-moz-user-focus", ""], ["-moz-user-input", ""], ["-moz-user-modify", ""], ["-moz-user-select", ""], ["vector-effect", ""], ["vertical-align", ""], ["visibility", ""], ["white-space", ""], ["width", ""], ["will-change", ""], ["-moz-window-dragging", ""], ["word-break", ""], ["word-spacing", ""], ["overflow-wrap", ""], ["writing-mode", ""], ["z-index", ""], ["word-wrap", ""], ["-moz-transform-origin", "layout.css.prefixes.transforms"], ["-moz-perspective-origin", "layout.css.prefixes.transforms"], ["-moz-perspective", "layout.css.prefixes.transforms"], ["-moz-transform-style", "layout.css.prefixes.transforms"], ["-moz-backface-visibility", "layout.css.prefixes.transforms"], ["-moz-border-image", "layout.css.prefixes.border-image"], ["-moz-transition", "layout.css.prefixes.transitions"], ["-moz-transition-delay", "layout.css.prefixes.transitions"], ["-moz-transition-duration", "layout.css.prefixes.transitions"], ["-moz-transition-property", "layout.css.prefixes.transitions"], ["-moz-transition-timing-function", "layout.css.prefixes.transitions"], ["-moz-animation", "layout.css.prefixes.animations"], ["-moz-animation-delay", "layout.css.prefixes.animations"], ["-moz-animation-direction", "layout.css.prefixes.animations"], ["-moz-animation-duration", "layout.css.prefixes.animations"], ["-moz-animation-fill-mode", "layout.css.prefixes.animations"], ["-moz-animation-iteration-count", "layout.css.prefixes.animations"], ["-moz-animation-name", "layout.css.prefixes.animations"], ["-moz-animation-play-state", "layout.css.prefixes.animations"], ["-moz-animation-timing-function", "layout.css.prefixes.animations"], ["-moz-box-sizing", "layout.css.prefixes.box-sizing"], ["-moz-font-feature-settings", "layout.css.prefixes.font-features"], ["-moz-font-language-override", "layout.css.prefixes.font-features"], ["-moz-padding-end", ""], ["-moz-padding-start", ""], ["-moz-margin-end", ""], ["-moz-margin-start", ""], ["-moz-border-end", ""], ["-moz-border-end-color", ""], ["-moz-border-end-style", ""], ["-moz-border-end-width", ""], ["-moz-border-start", ""], ["-moz-border-start-color", ""], ["-moz-border-start-style", ""], ["-moz-border-start-width", ""], ["-moz-hyphens", ""], ["-moz-text-align-last", ""], ["-webkit-animation", "layout.css.prefixes.webkit"], ["-webkit-animation-delay", "layout.css.prefixes.webkit"], ["-webkit-animation-direction", "layout.css.prefixes.webkit"], ["-webkit-animation-duration", "layout.css.prefixes.webkit"], ["-webkit-animation-fill-mode", "layout.css.prefixes.webkit"], ["-webkit-animation-iteration-count", "layout.css.prefixes.webkit"], ["-webkit-animation-name", "layout.css.prefixes.webkit"], ["-webkit-animation-play-state", "layout.css.prefixes.webkit"], ["-webkit-animation-timing-function", "layout.css.prefixes.webkit"], ["-webkit-filter", "layout.css.prefixes.webkit"], ["-webkit-text-size-adjust", "layout.css.prefixes.webkit"], ["-webkit-transform", "layout.css.prefixes.webkit"], ["-webkit-transform-origin", "layout.css.prefixes.webkit"], ["-webkit-transform-style", "layout.css.prefixes.webkit"], ["-webkit-backface-visibility", "layout.css.prefixes.webkit"], ["-webkit-perspective", "layout.css.prefixes.webkit"], ["-webkit-perspective-origin", "layout.css.prefixes.webkit"], ["-webkit-transition", "layout.css.prefixes.webkit"], ["-webkit-transition-delay", "layout.css.prefixes.webkit"], ["-webkit-transition-duration", "layout.css.prefixes.webkit"], ["-webkit-transition-property", "layout.css.prefixes.webkit"], ["-webkit-transition-timing-function", "layout.css.prefixes.webkit"], ["-webkit-border-radius", "layout.css.prefixes.webkit"], ["-webkit-border-top-left-radius", "layout.css.prefixes.webkit"], ["-webkit-border-top-right-radius", "layout.css.prefixes.webkit"], ["-webkit-border-bottom-left-radius", "layout.css.prefixes.webkit"], ["-webkit-border-bottom-right-radius", "layout.css.prefixes.webkit"], ["-webkit-background-clip", "layout.css.prefixes.webkit"], ["-webkit-background-origin", "layout.css.prefixes.webkit"], ["-webkit-background-size", "layout.css.prefixes.webkit"], ["-webkit-border-image", "layout.css.prefixes.webkit"], ["-webkit-box-shadow", "layout.css.prefixes.webkit"], ["-webkit-box-sizing", "layout.css.prefixes.webkit"], ["-webkit-box-flex", "layout.css.prefixes.webkit"], ["-webkit-box-ordinal-group", "layout.css.prefixes.webkit"], ["-webkit-box-orient", "layout.css.prefixes.webkit"], ["-webkit-box-direction", "layout.css.prefixes.webkit"], ["-webkit-box-align", "layout.css.prefixes.webkit"], ["-webkit-box-pack", "layout.css.prefixes.webkit"], ["-webkit-flex-direction", "layout.css.prefixes.webkit"], ["-webkit-flex-wrap", "layout.css.prefixes.webkit"], ["-webkit-flex-flow", "layout.css.prefixes.webkit"], ["-webkit-order", "layout.css.prefixes.webkit"], ["-webkit-flex", "layout.css.prefixes.webkit"], ["-webkit-flex-grow", "layout.css.prefixes.webkit"], ["-webkit-flex-shrink", "layout.css.prefixes.webkit"], ["-webkit-flex-basis", "layout.css.prefixes.webkit"], ["-webkit-justify-content", "layout.css.prefixes.webkit"], ["-webkit-align-items", "layout.css.prefixes.webkit"], ["-webkit-align-self", "layout.css.prefixes.webkit"], ["-webkit-align-content", "layout.css.prefixes.webkit"], ["-webkit-user-select", "layout.css.prefixes.webkit"], ["-webkit-mask", "layout.css.prefixes.webkit"], ["-webkit-mask-clip", "layout.css.prefixes.webkit"], ["-webkit-mask-composite", "layout.css.prefixes.webkit"], ["-webkit-mask-image", "layout.css.prefixes.webkit"], ["-webkit-mask-origin", "layout.css.prefixes.webkit"], ["-webkit-mask-position", "layout.css.prefixes.webkit"], ["-webkit-mask-position-x", "layout.css.prefixes.webkit"], ["-webkit-mask-position-y", "layout.css.prefixes.webkit"], ["-webkit-mask-repeat", "layout.css.prefixes.webkit"], ["-webkit-mask-size", "layout.css.prefixes.webkit"]];
 
 /* eslint-enable max-len */
--- a/devtools/shared/fronts/css-properties.js
+++ b/devtools/shared/fronts/css-properties.js
@@ -113,17 +113,36 @@ CssProperties.prototype = {
 
   /**
    * Gets the CSS property names.
    *
    * @return {Array} An array of strings.
    */
   getNames(property) {
     return Object.keys(this.properties);
-  }
+  },
+
+  /**
+   * Return a list of subproperties for the given property.  If |name|
+   * does not name a valid property, an empty array is returned.  If
+   * the property is not a shorthand property, then array containing
+   * just the property itself is returned.
+   *
+   * @param {String} name The property to query
+   * @return {Array} An array of subproperty names.
+   */
+  getSubproperties(name) {
+    if (this.isKnown(name)) {
+      if (this.properties[name] && this.properties[name].subproperties) {
+        return this.properties[name].subproperties;
+      }
+      return [name];
+    }
+    return [];
+  },
 };
 
 /**
  * Create a CssProperties object with a fully loaded CSS database. The
  * CssProperties interface can be queried synchronously, but the initialization
  * is potentially async and should be handled up-front when the tool is created.
  *
  * The front is returned only with this function so that it can be destroyed
@@ -227,16 +246,25 @@ function normalizeCssData(db) {
     // Add "values" information to the css properties if it's missing.
     if (!db.properties.color.values) {
       for (let name in db.properties) {
         if (typeof CSS_PROPERTIES_DB.properties[name] === "object") {
           db.properties[name].values = CSS_PROPERTIES_DB.properties[name].values;
         }
       }
     }
+
+    // Add "subproperties" information to the css properties if it's
+    // missing.
+    if (!db.properties.background.subproperties) {
+      for (let name in db.properties) {
+        db.properties[name].subproperties =
+          CSS_PROPERTIES_DB.properties[name].subproperties;
+      }
+    }
   }
 
   reattachCssColorValues(db);
 
   return db;
 }
 
 /**
--- a/devtools/shared/layout/utils.js
+++ b/devtools/shared/layout/utils.js
@@ -1,32 +1,35 @@
 /* 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 { Ci, Cc } = require("chrome");
-const { memoize } = require("sdk/lang/functional");
 const nodeFilterConstants = require("devtools/shared/dom-node-filter-constants");
 
 loader.lazyRequireGetter(this, "setIgnoreLayoutChanges", "devtools/server/actors/layout", true);
 exports.setIgnoreLayoutChanges = (...args) =>
   this.setIgnoreLayoutChanges(...args);
 
 /**
  * Returns the `DOMWindowUtils` for the window given.
  *
  * @param {DOMWindow} win
  * @returns {DOMWindowUtils}
  */
-const utilsFor = memoize(
-  win => win.QueryInterface(Ci.nsIInterfaceRequestor)
-            .getInterface(Ci.nsIDOMWindowUtils)
-);
+const utilsCache = new WeakMap();
+function utilsFor(win) {
+  if (!utilsCache.has(win)) {
+    utilsCache.set(win, win.QueryInterface(Ci.nsIInterfaceRequestor)
+                           .getInterface(Ci.nsIDOMWindowUtils));
+  }
+  return utilsCache.get(win);
+}
 
 /**
  * like win.top, but goes through mozbrowsers and mozapps iframes.
  *
  * @param {DOMWindow} win
  * @return {DOMWindow}
  */
 function getTopWindow(win) {
new file mode 100644
--- /dev/null
+++ b/devtools/shared/platform/content/.eslintrc
@@ -0,0 +1,9 @@
+{
+  // Extend from the devtools eslintrc.
+  "extends": "../../../.eslintrc",
+
+  "rules": {
+    // All code in this directory must be content-clean.
+    "mozilla/reject-some-requires": [2, "^(chrome|chrome:.*|resource:.*|devtools/server/.*|.*\\.jsm|devtools/shared/platform/(chome|content)/.*)$"],
+  },
+}
--- a/devtools/shared/platform/content/test/mochitest.ini
+++ b/devtools/shared/platform/content/test/mochitest.ini
@@ -1,4 +1,5 @@
 [DEFAULT]
 support-files =
 
 [test_clipboard.html]
+subsuite = clipboard
--- a/devtools/shared/specs/storage.js
+++ b/devtools/shared/specs/storage.js
@@ -148,17 +148,33 @@ types.addDictType("cachestoreobject", {
   total: "number",
   offset: "number",
   data: "array:nullable:cacheobject"
 });
 
 // Cache storage spec
 createStorageSpec({
   typeName: "Cache",
-  storeObjectType: "cachestoreobject"
+  storeObjectType: "cachestoreobject",
+  methods: {
+    removeAll: {
+      request: {
+        host: Arg(0, "string"),
+        name: Arg(1, "string"),
+      },
+      response: {}
+    },
+    removeItem: {
+      request: {
+        host: Arg(0, "string"),
+        name: Arg(1, "string"),
+      },
+      response: {}
+    },
+  }
 });
 
 // Indexed DB store object
 // This is a union on idb object, db metadata object and object store metadata
 // object
 types.addDictType("idbobject", {
   name: "nullable:string",
   db: "nullable:string",
--- a/dom/base/test/test_bug1295852.html
+++ b/dom/base/test/test_bug1295852.html
@@ -5,15 +5,19 @@
 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
 <body>
 <script>
 
 var names = [
   "span", "_moz_generated_content_before", "_moz_generated_content_after"
 ];
 
-names.forEach(name => {
-  var element = document.createElement(name);
-  element.animate({ "color": ["red", "blue"] }, { duration: 1000 });
-  is(element.getAnimations().length, 1);
-});
+if (SpecialPowers.getBoolPref("dom.animations-api.core.enabled")) {
+  names.forEach(name => {
+    var element = document.createElement(name);
+    element.animate({ "color": ["red", "blue"] }, { duration: 1000 });
+    is(element.getAnimations().length, 1);
+  });
+} else {
+  ok("Test requires Web Animations, which is disabled.");
+}
 
 </script>
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -10250,25 +10250,28 @@ class ClassDestructor(ClassItem):
             """,
             decorators=self.getDecorators(False),
             className=cgClass.getNameString(),
             body=self.getBody())
 
 
 class ClassMember(ClassItem):
     def __init__(self, name, type, visibility="private", static=False,
-                 body=None):
+                 body=None, hasIgnoreInitCheckFlag=False):
         self.type = type
         self.static = static
         self.body = body
+        self.hasIgnoreInitCheckFlag = hasIgnoreInitCheckFlag;
         ClassItem.__init__(self, name, visibility)
 
     def declare(self, cgClass):
-        return '%s%s %s;\n' % ('static ' if self.static else '', self.type,
-                               self.name)
+        return '%s%s%s %s;\n' % ('static ' if self.static else '',
+                                 'MOZ_INIT_OUTSIDE_CTOR '
+                                 if self.hasIgnoreInitCheckFlag else '',
+                                 self.type, self.name)
 
     def define(self, cgClass):
         if not self.static:
             return ''
         if self.body:
             body = " = " + self.body
         else:
             body = ""
@@ -12514,17 +12517,18 @@ class CGDictionary(CGThing):
             body=body.define())
 
     def getStructs(self):
         d = self.dictionary
         selfName = self.makeClassName(d)
         members = [ClassMember(self.makeMemberName(m[0].identifier.name),
                                self.getMemberType(m),
                                visibility="public",
-                               body=self.getMemberInitializer(m))
+                               body=self.getMemberInitializer(m),
+                               hasIgnoreInitCheckFlag=True)
                    for m in self.memberInfo]
         if d.parent:
             # We always want to init our parent with our non-initializing
             # constructor arg, because either we're about to init ourselves (and
             # hence our parent) or we don't want any init happening.
             baseConstructors = [
                 "%s(%s)" % (self.makeClassName(d.parent),
                             self.getNonInitializingCtorArg())
--- a/dom/events/VirtualKeyCodeList.h
+++ b/dom/events/VirtualKeyCodeList.h
@@ -7,221 +7,234 @@
 
 /**
  * This header file defines all DOM keys which are defined in nsIDOMKeyEvent.
  * You must define NS_DEFINE_VK macro before including this.
  *
  * It must have two arguments, (aDOMKeyName, aDOMKeyCode)
  * aDOMKeyName is a key name in DOM.
  * aDOMKeyCode is one of nsIDOMKeyEvent::DOM_VK_*.
+ *
+ * Optionally, you can define NS_DISALLOW_SAME_KEYCODE.
+ *
+ * If NS_DISALLOW_SAME_KEYCODE is defined, same keyCode won't listed up.
+ * This is useful when you create switch-case statement.
  */
 
 #define DEFINE_VK_INTERNAL(aKeyName) \
   NS_DEFINE_VK(VK##aKeyName, nsIDOMKeyEvent::DOM_VK##aKeyName)
 
 // Some keycode may have different name in nsIDOMKeyEvent from its key name.
 #define DEFINE_VK_INTERNAL2(aKeyName, aKeyCodeName) \
   NS_DEFINE_VK(VK##aKeyName, nsIDOMKeyEvent::DOM_VK##aKeyCodeName)
 
-DEFINE_VK_INTERNAL(_CANCEL),
-DEFINE_VK_INTERNAL(_HELP),
-DEFINE_VK_INTERNAL2(_BACK, _BACK_SPACE),
-DEFINE_VK_INTERNAL(_TAB),
-DEFINE_VK_INTERNAL(_CLEAR),
-DEFINE_VK_INTERNAL(_RETURN),
-DEFINE_VK_INTERNAL(_SHIFT),
-DEFINE_VK_INTERNAL(_CONTROL),
-DEFINE_VK_INTERNAL(_ALT),
-DEFINE_VK_INTERNAL(_PAUSE),
-DEFINE_VK_INTERNAL(_CAPS_LOCK),
-DEFINE_VK_INTERNAL(_KANA),
-DEFINE_VK_INTERNAL(_HANGUL),
-DEFINE_VK_INTERNAL(_EISU),
-DEFINE_VK_INTERNAL(_JUNJA),
-DEFINE_VK_INTERNAL(_FINAL),
-DEFINE_VK_INTERNAL(_HANJA),
-DEFINE_VK_INTERNAL(_KANJI),
-DEFINE_VK_INTERNAL(_ESCAPE),
-DEFINE_VK_INTERNAL(_CONVERT),
-DEFINE_VK_INTERNAL(_NONCONVERT),
-DEFINE_VK_INTERNAL(_ACCEPT),
-DEFINE_VK_INTERNAL(_MODECHANGE),
-DEFINE_VK_INTERNAL(_SPACE),
-DEFINE_VK_INTERNAL(_PAGE_UP),
-DEFINE_VK_INTERNAL(_PAGE_DOWN),
-DEFINE_VK_INTERNAL(_END),
-DEFINE_VK_INTERNAL(_HOME),
-DEFINE_VK_INTERNAL(_LEFT),
-DEFINE_VK_INTERNAL(_UP),
-DEFINE_VK_INTERNAL(_RIGHT),
-DEFINE_VK_INTERNAL(_DOWN),
-DEFINE_VK_INTERNAL(_SELECT),
-DEFINE_VK_INTERNAL(_PRINT),
-DEFINE_VK_INTERNAL(_EXECUTE),
-DEFINE_VK_INTERNAL(_PRINTSCREEN),
-DEFINE_VK_INTERNAL(_INSERT),
-DEFINE_VK_INTERNAL(_DELETE),
+DEFINE_VK_INTERNAL(_CANCEL)
+DEFINE_VK_INTERNAL(_HELP)
+DEFINE_VK_INTERNAL2(_BACK, _BACK_SPACE)
+DEFINE_VK_INTERNAL(_TAB)
+DEFINE_VK_INTERNAL(_CLEAR)
+DEFINE_VK_INTERNAL(_RETURN)
+DEFINE_VK_INTERNAL(_SHIFT)
+DEFINE_VK_INTERNAL(_CONTROL)
+DEFINE_VK_INTERNAL(_ALT)
+DEFINE_VK_INTERNAL(_PAUSE)
+DEFINE_VK_INTERNAL(_CAPS_LOCK)
+#ifdef NS_DISALLOW_SAME_KEYCODE
+DEFINE_VK_INTERNAL2(_KANA_OR_HANGUL, _KANA)
+#else // #ifdef NS_DISALLOW_SAME_KEYCODE
+DEFINE_VK_INTERNAL(_KANA)
+DEFINE_VK_INTERNAL(_HANGUL)
+#endif
+DEFINE_VK_INTERNAL(_EISU)
+DEFINE_VK_INTERNAL(_JUNJA)
+DEFINE_VK_INTERNAL(_FINAL)
+#ifdef NS_DISALLOW_SAME_KEYCODE
+DEFINE_VK_INTERNAL2(_HANJA_OR_KANJI, _HANJA)
+#else // #ifdef NS_DISALLOW_SAME_KEYCODE
+DEFINE_VK_INTERNAL(_HANJA)
+DEFINE_VK_INTERNAL(_KANJI)
+#endif
+DEFINE_VK_INTERNAL(_ESCAPE)
+DEFINE_VK_INTERNAL(_CONVERT)
+DEFINE_VK_INTERNAL(_NONCONVERT)
+DEFINE_VK_INTERNAL(_ACCEPT)
+DEFINE_VK_INTERNAL(_MODECHANGE)
+DEFINE_VK_INTERNAL(_SPACE)
+DEFINE_VK_INTERNAL(_PAGE_UP)
+DEFINE_VK_INTERNAL(_PAGE_DOWN)
+DEFINE_VK_INTERNAL(_END)
+DEFINE_VK_INTERNAL(_HOME)
+DEFINE_VK_INTERNAL(_LEFT)
+DEFINE_VK_INTERNAL(_UP)
+DEFINE_VK_INTERNAL(_RIGHT)
+DEFINE_VK_INTERNAL(_DOWN)
+DEFINE_VK_INTERNAL(_SELECT)
+DEFINE_VK_INTERNAL(_PRINT)
+DEFINE_VK_INTERNAL(_EXECUTE)
+DEFINE_VK_INTERNAL(_PRINTSCREEN)
+DEFINE_VK_INTERNAL(_INSERT)
+DEFINE_VK_INTERNAL(_DELETE)
 
-DEFINE_VK_INTERNAL(_0),
-DEFINE_VK_INTERNAL(_1),
-DEFINE_VK_INTERNAL(_2),
-DEFINE_VK_INTERNAL(_3),
-DEFINE_VK_INTERNAL(_4),
-DEFINE_VK_INTERNAL(_5),
-DEFINE_VK_INTERNAL(_6),
-DEFINE_VK_INTERNAL(_7),
-DEFINE_VK_INTERNAL(_8),
-DEFINE_VK_INTERNAL(_9),
+DEFINE_VK_INTERNAL(_0)
+DEFINE_VK_INTERNAL(_1)
+DEFINE_VK_INTERNAL(_2)
+DEFINE_VK_INTERNAL(_3)
+DEFINE_VK_INTERNAL(_4)
+DEFINE_VK_INTERNAL(_5)
+DEFINE_VK_INTERNAL(_6)
+DEFINE_VK_INTERNAL(_7)
+DEFINE_VK_INTERNAL(_8)
+DEFINE_VK_INTERNAL(_9)
 
-DEFINE_VK_INTERNAL(_COLON),
-DEFINE_VK_INTERNAL(_SEMICOLON),
-DEFINE_VK_INTERNAL(_LESS_THAN),
-DEFINE_VK_INTERNAL(_EQUALS),
-DEFINE_VK_INTERNAL(_GREATER_THAN),
-DEFINE_VK_INTERNAL(_QUESTION_MARK),
-DEFINE_VK_INTERNAL(_AT),
+DEFINE_VK_INTERNAL(_COLON)
+DEFINE_VK_INTERNAL(_SEMICOLON)
+DEFINE_VK_INTERNAL(_LESS_THAN)
+DEFINE_VK_INTERNAL(_EQUALS)
+DEFINE_VK_INTERNAL(_GREATER_THAN)
+DEFINE_VK_INTERNAL(_QUESTION_MARK)
+DEFINE_VK_INTERNAL(_AT)
 
-DEFINE_VK_INTERNAL(_A),
-DEFINE_VK_INTERNAL(_B),
-DEFINE_VK_INTERNAL(_C),
-DEFINE_VK_INTERNAL(_D),
-DEFINE_VK_INTERNAL(_E),
-DEFINE_VK_INTERNAL(_F),
-DEFINE_VK_INTERNAL(_G),
-DEFINE_VK_INTERNAL(_H),
-DEFINE_VK_INTERNAL(_I),
-DEFINE_VK_INTERNAL(_J),
-DEFINE_VK_INTERNAL(_K),
-DEFINE_VK_INTERNAL(_L),
-DEFINE_VK_INTERNAL(_M),
-DEFINE_VK_INTERNAL(_N),
-DEFINE_VK_INTERNAL(_O),
-DEFINE_VK_INTERNAL(_P),
-DEFINE_VK_INTERNAL(_Q),
-DEFINE_VK_INTERNAL(_R),
-DEFINE_VK_INTERNAL(_S),
-DEFINE_VK_INTERNAL(_T),
-DEFINE_VK_INTERNAL(_U),
-DEFINE_VK_INTERNAL(_V),
-DEFINE_VK_INTERNAL(_W),
-DEFINE_VK_INTERNAL(_X),
-DEFINE_VK_INTERNAL(_Y),
-DEFINE_VK_INTERNAL(_Z),
+DEFINE_VK_INTERNAL(_A)
+DEFINE_VK_INTERNAL(_B)
+DEFINE_VK_INTERNAL(_C)
+DEFINE_VK_INTERNAL(_D)
+DEFINE_VK_INTERNAL(_E)
+DEFINE_VK_INTERNAL(_F)
+DEFINE_VK_INTERNAL(_G)
+DEFINE_VK_INTERNAL(_H)
+DEFINE_VK_INTERNAL(_I)
+DEFINE_VK_INTERNAL(_J)
+DEFINE_VK_INTERNAL(_K)
+DEFINE_VK_INTERNAL(_L)
+DEFINE_VK_INTERNAL(_M)
+DEFINE_VK_INTERNAL(_N)
+DEFINE_VK_INTERNAL(_O)
+DEFINE_VK_INTERNAL(_P)
+DEFINE_VK_INTERNAL(_Q)
+DEFINE_VK_INTERNAL(_R)
+DEFINE_VK_INTERNAL(_S)
+DEFINE_VK_INTERNAL(_T)
+DEFINE_VK_INTERNAL(_U)
+DEFINE_VK_INTERNAL(_V)
+DEFINE_VK_INTERNAL(_W)
+DEFINE_VK_INTERNAL(_X)
+DEFINE_VK_INTERNAL(_Y)
+DEFINE_VK_INTERNAL(_Z)
 
-DEFINE_VK_INTERNAL(_WIN),
-DEFINE_VK_INTERNAL(_CONTEXT_MENU),
-DEFINE_VK_INTERNAL(_SLEEP),
+DEFINE_VK_INTERNAL(_WIN)
+DEFINE_VK_INTERNAL(_CONTEXT_MENU)
+DEFINE_VK_INTERNAL(_SLEEP)
 
-DEFINE_VK_INTERNAL(_NUMPAD0),
-DEFINE_VK_INTERNAL(_NUMPAD1),
-DEFINE_VK_INTERNAL(_NUMPAD2),
-DEFINE_VK_INTERNAL(_NUMPAD3),
-DEFINE_VK_INTERNAL(_NUMPAD4),
-DEFINE_VK_INTERNAL(_NUMPAD5),
-DEFINE_VK_INTERNAL(_NUMPAD6),
-DEFINE_VK_INTERNAL(_NUMPAD7),
-DEFINE_VK_INTERNAL(_NUMPAD8),
-DEFINE_VK_INTERNAL(_NUMPAD9),
-DEFINE_VK_INTERNAL(_MULTIPLY),
-DEFINE_VK_INTERNAL(_ADD),
-DEFINE_VK_INTERNAL(_SEPARATOR),
-DEFINE_VK_INTERNAL(_SUBTRACT),
-DEFINE_VK_INTERNAL(_DECIMAL),
-DEFINE_VK_INTERNAL(_DIVIDE),
+DEFINE_VK_INTERNAL(_NUMPAD0)
+DEFINE_VK_INTERNAL(_NUMPAD1)
+DEFINE_VK_INTERNAL(_NUMPAD2)
+DEFINE_VK_INTERNAL(_NUMPAD3)
+DEFINE_VK_INTERNAL(_NUMPAD4)
+DEFINE_VK_INTERNAL(_NUMPAD5)
+DEFINE_VK_INTERNAL(_NUMPAD6)
+DEFINE_VK_INTERNAL(_NUMPAD7)
+DEFINE_VK_INTERNAL(_NUMPAD8)
+DEFINE_VK_INTERNAL(_NUMPAD9)
+DEFINE_VK_INTERNAL(_MULTIPLY)
+DEFINE_VK_INTERNAL(_ADD)
+DEFINE_VK_INTERNAL(_SEPARATOR)
+DEFINE_VK_INTERNAL(_SUBTRACT)
+DEFINE_VK_INTERNAL(_DECIMAL)
+DEFINE_VK_INTERNAL(_DIVIDE)
 
-DEFINE_VK_INTERNAL(_F1),
-DEFINE_VK_INTERNAL(_F2),
-DEFINE_VK_INTERNAL(_F3),
-DEFINE_VK_INTERNAL(_F4),
-DEFINE_VK_INTERNAL(_F5),
-DEFINE_VK_INTERNAL(_F6),
-DEFINE_VK_INTERNAL(_F7),
-DEFINE_VK_INTERNAL(_F8),
-DEFINE_VK_INTERNAL(_F9),
-DEFINE_VK_INTERNAL(_F10),
-DEFINE_VK_INTERNAL(_F11),
-DEFINE_VK_INTERNAL(_F12),
-DEFINE_VK_INTERNAL(_F13),
-DEFINE_VK_INTERNAL(_F14),
-DEFINE_VK_INTERNAL(_F15),
-DEFINE_VK_INTERNAL(_F16),
-DEFINE_VK_INTERNAL(_F17),
-DEFINE_VK_INTERNAL(_F18),
-DEFINE_VK_INTERNAL(_F19),
-DEFINE_VK_INTERNAL(_F20),
-DEFINE_VK_INTERNAL(_F21),
-DEFINE_VK_INTERNAL(_F22),
-DEFINE_VK_INTERNAL(_F23),
-DEFINE_VK_INTERNAL(_F24),
+DEFINE_VK_INTERNAL(_F1)
+DEFINE_VK_INTERNAL(_F2)
+DEFINE_VK_INTERNAL(_F3)
+DEFINE_VK_INTERNAL(_F4)
+DEFINE_VK_INTERNAL(_F5)
+DEFINE_VK_INTERNAL(_F6)
+DEFINE_VK_INTERNAL(_F7)
+DEFINE_VK_INTERNAL(_F8)
+DEFINE_VK_INTERNAL(_F9)
+DEFINE_VK_INTERNAL(_F10)
+DEFINE_VK_INTERNAL(_F11)
+DEFINE_VK_INTERNAL(_F12)
+DEFINE_VK_INTERNAL(_F13)
+DEFINE_VK_INTERNAL(_F14)
+DEFINE_VK_INTERNAL(_F15)
+DEFINE_VK_INTERNAL(_F16)
+DEFINE_VK_INTERNAL(_F17)
+DEFINE_VK_INTERNAL(_F18)
+DEFINE_VK_INTERNAL(_F19)
+DEFINE_VK_INTERNAL(_F20)
+DEFINE_VK_INTERNAL(_F21)
+DEFINE_VK_INTERNAL(_F22)
+DEFINE_VK_INTERNAL(_F23)
+DEFINE_VK_INTERNAL(_F24)
 
-DEFINE_VK_INTERNAL(_NUM_LOCK),
-DEFINE_VK_INTERNAL(_SCROLL_LOCK),
+DEFINE_VK_INTERNAL(_NUM_LOCK)
+DEFINE_VK_INTERNAL(_SCROLL_LOCK)
 
-DEFINE_VK_INTERNAL(_WIN_OEM_FJ_JISHO),
-DEFINE_VK_INTERNAL(_WIN_OEM_FJ_MASSHOU),
-DEFINE_VK_INTERNAL(_WIN_OEM_FJ_TOUROKU),
-DEFINE_VK_INTERNAL(_WIN_OEM_FJ_LOYA),
-DEFINE_VK_INTERNAL(_WIN_OEM_FJ_ROYA),
+DEFINE_VK_INTERNAL(_WIN_OEM_FJ_JISHO)
+DEFINE_VK_INTERNAL(_WIN_OEM_FJ_MASSHOU)
+DEFINE_VK_INTERNAL(_WIN_OEM_FJ_TOUROKU)
+DEFINE_VK_INTERNAL(_WIN_OEM_FJ_LOYA)
+DEFINE_VK_INTERNAL(_WIN_OEM_FJ_ROYA)
 
-DEFINE_VK_INTERNAL(_CIRCUMFLEX),
-DEFINE_VK_INTERNAL(_EXCLAMATION),
-DEFINE_VK_INTERNAL(_DOUBLE_QUOTE),
-DEFINE_VK_INTERNAL(_HASH),
-DEFINE_VK_INTERNAL(_DOLLAR),
-DEFINE_VK_INTERNAL(_PERCENT),
-DEFINE_VK_INTERNAL(_AMPERSAND),
-DEFINE_VK_INTERNAL(_UNDERSCORE),
-DEFINE_VK_INTERNAL(_OPEN_PAREN),
-DEFINE_VK_INTERNAL(_CLOSE_PAREN),
-DEFINE_VK_INTERNAL(_ASTERISK),
-DEFINE_VK_INTERNAL(_PLUS),
-DEFINE_VK_INTERNAL(_PIPE),
-DEFINE_VK_INTERNAL(_HYPHEN_MINUS),
+DEFINE_VK_INTERNAL(_CIRCUMFLEX)
+DEFINE_VK_INTERNAL(_EXCLAMATION)
+DEFINE_VK_INTERNAL(_DOUBLE_QUOTE)
+DEFINE_VK_INTERNAL(_HASH)
+DEFINE_VK_INTERNAL(_DOLLAR)
+DEFINE_VK_INTERNAL(_PERCENT)
+DEFINE_VK_INTERNAL(_AMPERSAND)
+DEFINE_VK_INTERNAL(_UNDERSCORE)
+DEFINE_VK_INTERNAL(_OPEN_PAREN)
+DEFINE_VK_INTERNAL(_CLOSE_PAREN)
+DEFINE_VK_INTERNAL(_ASTERISK)
+DEFINE_VK_INTERNAL(_PLUS)
+DEFINE_VK_INTERNAL(_PIPE)
+DEFINE_VK_INTERNAL(_HYPHEN_MINUS)
 
-DEFINE_VK_INTERNAL(_OPEN_CURLY_BRACKET),
-DEFINE_VK_INTERNAL(_CLOSE_CURLY_BRACKET),
+DEFINE_VK_INTERNAL(_OPEN_CURLY_BRACKET)
+DEFINE_VK_INTERNAL(_CLOSE_CURLY_BRACKET)
 
-DEFINE_VK_INTERNAL(_TILDE),
+DEFINE_VK_INTERNAL(_TILDE)
 
-DEFINE_VK_INTERNAL(_VOLUME_MUTE),
-DEFINE_VK_INTERNAL(_VOLUME_DOWN),
-DEFINE_VK_INTERNAL(_VOLUME_UP),
+DEFINE_VK_INTERNAL(_VOLUME_MUTE)
+DEFINE_VK_INTERNAL(_VOLUME_DOWN)
+DEFINE_VK_INTERNAL(_VOLUME_UP)
 
-DEFINE_VK_INTERNAL(_COMMA),
-DEFINE_VK_INTERNAL(_PERIOD),
-DEFINE_VK_INTERNAL(_SLASH),
-DEFINE_VK_INTERNAL(_BACK_QUOTE),
-DEFINE_VK_INTERNAL(_OPEN_BRACKET),
-DEFINE_VK_INTERNAL(_BACK_SLASH),
-DEFINE_VK_INTERNAL(_CLOSE_BRACKET),
-DEFINE_VK_INTERNAL(_QUOTE),
+DEFINE_VK_INTERNAL(_COMMA)
+DEFINE_VK_INTERNAL(_PERIOD)
+DEFINE_VK_INTERNAL(_SLASH)
+DEFINE_VK_INTERNAL(_BACK_QUOTE)
+DEFINE_VK_INTERNAL(_OPEN_BRACKET)
+DEFINE_VK_INTERNAL(_BACK_SLASH)
+DEFINE_VK_INTERNAL(_CLOSE_BRACKET)
+DEFINE_VK_INTERNAL(_QUOTE)
 
-DEFINE_VK_INTERNAL(_META),
-DEFINE_VK_INTERNAL(_ALTGR),
+DEFINE_VK_INTERNAL(_META)
+DEFINE_VK_INTERNAL(_ALTGR)
 
-DEFINE_VK_INTERNAL(_WIN_ICO_HELP),
-DEFINE_VK_INTERNAL(_WIN_ICO_00),
-DEFINE_VK_INTERNAL(_WIN_ICO_CLEAR),
-DEFINE_VK_INTERNAL(_WIN_OEM_RESET),
-DEFINE_VK_INTERNAL(_WIN_OEM_JUMP),
-DEFINE_VK_INTERNAL(_WIN_OEM_PA1),
-DEFINE_VK_INTERNAL(_WIN_OEM_PA2),
-DEFINE_VK_INTERNAL(_WIN_OEM_PA3),
-DEFINE_VK_INTERNAL(_WIN_OEM_WSCTRL),
-DEFINE_VK_INTERNAL(_WIN_OEM_CUSEL),
-DEFINE_VK_INTERNAL(_WIN_OEM_ATTN),
-DEFINE_VK_INTERNAL(_WIN_OEM_FINISH),
-DEFINE_VK_INTERNAL(_WIN_OEM_COPY),
-DEFINE_VK_INTERNAL(_WIN_OEM_AUTO),
-DEFINE_VK_INTERNAL(_WIN_OEM_ENLW),
-DEFINE_VK_INTERNAL(_WIN_OEM_BACKTAB),
+DEFINE_VK_INTERNAL(_WIN_ICO_HELP)
+DEFINE_VK_INTERNAL(_WIN_ICO_00)
+DEFINE_VK_INTERNAL(_WIN_ICO_CLEAR)
+DEFINE_VK_INTERNAL(_WIN_OEM_RESET)
+DEFINE_VK_INTERNAL(_WIN_OEM_JUMP)
+DEFINE_VK_INTERNAL(_WIN_OEM_PA1)
+DEFINE_VK_INTERNAL(_WIN_OEM_PA2)
+DEFINE_VK_INTERNAL(_WIN_OEM_PA3)
+DEFINE_VK_INTERNAL(_WIN_OEM_WSCTRL)
+DEFINE_VK_INTERNAL(_WIN_OEM_CUSEL)
+DEFINE_VK_INTERNAL(_WIN_OEM_ATTN)
+DEFINE_VK_INTERNAL(_WIN_OEM_FINISH)
+DEFINE_VK_INTERNAL(_WIN_OEM_COPY)
+DEFINE_VK_INTERNAL(_WIN_OEM_AUTO)
+DEFINE_VK_INTERNAL(_WIN_OEM_ENLW)
+DEFINE_VK_INTERNAL(_WIN_OEM_BACKTAB)
 
-DEFINE_VK_INTERNAL(_ATTN),
-DEFINE_VK_INTERNAL(_CRSEL),
-DEFINE_VK_INTERNAL(_EXSEL),
-DEFINE_VK_INTERNAL(_EREOF),
-DEFINE_VK_INTERNAL(_PLAY),
-DEFINE_VK_INTERNAL(_ZOOM),
-DEFINE_VK_INTERNAL(_PA1),
+DEFINE_VK_INTERNAL(_ATTN)
+DEFINE_VK_INTERNAL(_CRSEL)
+DEFINE_VK_INTERNAL(_EXSEL)
+DEFINE_VK_INTERNAL(_EREOF)
+DEFINE_VK_INTERNAL(_PLAY)
+DEFINE_VK_INTERNAL(_ZOOM)
+DEFINE_VK_INTERNAL(_PA1)
 DEFINE_VK_INTERNAL(_WIN_OEM_CLEAR)
 
 #undef DEFINE_VK_INTERNAL
 #undef DEFINE_VK_INTERNAL2
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -459,17 +459,33 @@ public:
     if (!mDecodeStartTime.IsNull()) {
       TimeDuration decodeDuration = TimeStamp::Now() - mDecodeStartTime;
       SLOG("Exiting DECODING, decoded for %.3lfs", decodeDuration.ToSeconds());
     }
   }
 
   void Step() override
   {
-    mMaster->StepDecoding();
+    if (mMaster->mPlayState != MediaDecoder::PLAY_STATE_PLAYING &&
+        mMaster->IsPlaying()) {
+      // We're playing, but the element/decoder is in paused state. Stop
+      // playing!
+      mMaster->StopPlayback();
+    }
+
+    // Start playback if necessary so that the clock can be properly queried.
+    mMaster->MaybeStartPlayback();
+
+    mMaster->UpdatePlaybackPositionPeriodically();
+
+    MOZ_ASSERT(!mMaster->IsPlaying() ||
+               mMaster->IsStateMachineScheduled(),
+               "Must have timer scheduled");
+
+    mMaster->MaybeStartBuffering();
   }
 
   State GetState() const override
   {
     return DECODER_STATE_DECODING;
   }
 
 private:
@@ -591,28 +607,69 @@ public:
 
   void Enter() override
   {
     mMaster->ScheduleStateMachine();
   }
 
   void Exit() override
   {
-    mMaster->mSentPlaybackEndedEvent = false;
+    mSentPlaybackEndedEvent = false;
   }
 
   void Step() override
   {
-    mMaster->StepCompleted();
+    if (mMaster->mPlayState != MediaDecoder::PLAY_STATE_PLAYING &&
+        mMaster->IsPlaying()) {
+      mMaster->StopPlayback();
+    }
+
+    // Play the remaining media. We want to run AdvanceFrame() at least
+    // once to ensure the current playback position is advanced to the
+    // end of the media, and so that we update the readyState.
+    if ((mMaster->HasVideo() && !mMaster->mVideoCompleted) ||
+        (mMaster->HasAudio() && !mMaster->mAudioCompleted)) {
+      // Start playback if necessary to play the remaining media.
+      mMaster->MaybeStartPlayback();
+      mMaster->UpdatePlaybackPositionPeriodically();
+      MOZ_ASSERT(!mMaster->IsPlaying() ||
+                 mMaster->IsStateMachineScheduled(),
+                 "Must have timer scheduled");
+      return;
+    }
+
+    // StopPlayback in order to reset the IsPlaying() state so audio
+    // is restarted correctly.
+    mMaster->StopPlayback();
+
+    if (mMaster->mPlayState == MediaDecoder::PLAY_STATE_PLAYING &&
+        !mSentPlaybackEndedEvent) {
+      int64_t clockTime = std::max(mMaster->AudioEndTime(), mMaster->VideoEndTime());
+      clockTime = std::max(int64_t(0), std::max(clockTime, mMaster->Duration().ToMicroseconds()));
+      mMaster->UpdatePlaybackPosition(clockTime);
+
+      // Ensure readyState is updated before firing the 'ended' event.
+      mMaster->UpdateNextFrameStatus();
+
+      mMaster->mOnPlaybackEvent.Notify(MediaEventType::PlaybackEnded);
+
+      mSentPlaybackEndedEvent = true;
+
+      // MediaSink::GetEndTime() must be called before stopping playback.
+      mMaster->StopMediaSink();
+    }
   }
 
   State GetState() const override
   {
     return DECODER_STATE_COMPLETED;
   }
+
+private:
+  bool mSentPlaybackEndedEvent = false;
 };
 
 class MediaDecoderStateMachine::ShutdownState
   : public MediaDecoderStateMachine::StateObject
 {
 public:
   explicit ShutdownState(Master* aPtr) : StateObject(aPtr) {}
 
@@ -671,17 +728,16 @@ MediaDecoderStateMachine::MediaDecoderSt
   mAudioCaptured(false),
   INIT_WATCHABLE(mAudioCompleted, false),
   INIT_WATCHABLE(mVideoCompleted, false),
   mNotifyMetadataBeforeFirstFrame(false),
   mMinimizePreroll(false),
   mDecodeThreadWaiting(false),
   mSentLoadedMetadataEvent(false),
   mSentFirstFrameLoadedEvent(false),
-  mSentPlaybackEndedEvent(false),
   mVideoDecodeSuspended(false),
   mVideoDecodeSuspendTimer(mTaskQueue),
   mOutputStreamManager(new OutputStreamManager()),
   mResource(aDecoder->GetResource()),
   mAudioOffloading(false),
   INIT_MIRROR(mBuffered, TimeIntervals()),
   INIT_MIRROR(mIsReaderSuspended, true),
   INIT_MIRROR(mEstimatedDuration, NullableTimeUnit()),
@@ -2520,84 +2576,16 @@ MediaDecoderStateMachine::RunStateMachin
   MOZ_ASSERT(OnTaskQueue());
 
   mDelayedScheduler.Reset(); // Must happen on state machine task queue.
   mDispatchedStateMachine = false;
   mStateObj->Step();
 }
 
 void
-MediaDecoderStateMachine::StepDecoding()
-{
-  MOZ_ASSERT(OnTaskQueue());
-
-  if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING && IsPlaying()) {
-    // We're playing, but the element/decoder is in paused state. Stop
-    // playing!
-    StopPlayback();
-  }
-
-  // Start playback if necessary so that the clock can be properly queried.
-  MaybeStartPlayback();
-
-  UpdatePlaybackPositionPeriodically();
-
-  NS_ASSERTION(!IsPlaying() ||
-               IsStateMachineScheduled(),
-               "Must have timer scheduled");
-
-  MaybeStartBuffering();
-}
-
-void
-MediaDecoderStateMachine::StepCompleted()
-{
-  MOZ_ASSERT(OnTaskQueue());
-
-  if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING && IsPlaying()) {
-    StopPlayback();
-  }
-
-  // Play the remaining media. We want to run AdvanceFrame() at least
-  // once to ensure the current playback position is advanced to the
-  // end of the media, and so that we update the readyState.
-  if ((HasVideo() && !mVideoCompleted) ||
-      (HasAudio() && !mAudioCompleted)) {
-    // Start playback if necessary to play the remaining media.
-    MaybeStartPlayback();
-    UpdatePlaybackPositionPeriodically();
-    NS_ASSERTION(!IsPlaying() ||
-                 IsStateMachineScheduled(),
-                 "Must have timer scheduled");
-    return;
-  }
-
-  // StopPlayback in order to reset the IsPlaying() state so audio
-  // is restarted correctly.
-  StopPlayback();
-
-  if (mPlayState == MediaDecoder::PLAY_STATE_PLAYING &&
-      !mSentPlaybackEndedEvent) {
-    int64_t clockTime = std::max(AudioEndTime(), VideoEndTime());
-    clockTime = std::max(int64_t(0), std::max(clockTime, Duration().ToMicroseconds()));
-    UpdatePlaybackPosition(clockTime);
-
-    // Ensure readyState is updated before firing the 'ended' event.
-    UpdateNextFrameStatus();
-
-    mOnPlaybackEvent.Notify(MediaEventType::PlaybackEnded);
-
-    mSentPlaybackEndedEvent = true;
-
-    // MediaSink::GetEndTime() must be called before stopping playback.
-    StopMediaSink();
-  }
-}
-
-void
 MediaDecoderStateMachine::Reset(TrackSet aTracks)
 {
   MOZ_ASSERT(OnTaskQueue());
   DECODER_LOG("MediaDecoderStateMachine::Reset");
 
   // We should be resetting because we're seeking, shutting down, or entering
   // dormant state. We could also be in the process of going dormant, and have
   // just switched to exiting dormant before we finished entering dormant,
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -533,20 +533,16 @@ protected:
   // Completes the seek operation, moves onto the next appropriate state.
   void SeekCompleted();
 
   // Queries our state to see whether the decode has finished for all streams.
   bool CheckIfDecodeComplete();
 
   // Performs one "cycle" of the state machine.
   void RunStateMachine();
-  // Perform one cycle of the DECODING state.
-  void StepDecoding();
-  // Perform one cycle of the COMPLETED state.
-  void StepCompleted();
 
   bool IsStateMachineScheduled() const;
 
   // These return true if the respective stream's decode has not yet reached
   // the end of stream.
   bool IsAudioDecoding();
   bool IsVideoDecoding();
 
@@ -826,18 +822,16 @@ private:
   bool mSentLoadedMetadataEvent;
 
   // True if we've decoded first frames (thus having the start time) and
   // notified the FirstFrameLoaded event. Note we can't initiate seek until the
   // start time is known which happens when the first frames are decoded or we
   // are playing an MSE stream (the start time is always assumed 0).
   bool mSentFirstFrameLoadedEvent;
 
-  bool mSentPlaybackEndedEvent;
-
   // True if video decoding is suspended.
   bool mVideoDecodeSuspended;
 
   // Track enabling video decode suspension via timer
   DelayedScheduler mVideoDecodeSuspendTimer;
 
   // Data about MediaStreams that are being fed by the decoder.
   const RefPtr<OutputStreamManager> mOutputStreamManager;
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -39,16 +39,18 @@
 #include "nsExceptionHandler.h"
 #include "nsPrintfCString.h"
 #endif
 #include "nsIXULRuntime.h"
 #include "GMPDecoderModule.h"
 #include <limits>
 #include "MediaPrefs.h"
 
+using mozilla::ipc::Transport;
+
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 #define LOGD(msg) MOZ_LOG(GetGMPLog(), mozilla::LogLevel::Debug, msg)
 #define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
@@ -75,27 +77,29 @@ GeckoMediaPluginServiceParent::GetSingle
     MOZ_ASSERT(chromeService);
   }
 #endif
   return service.forget().downcast<GeckoMediaPluginServiceParent>();
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(GeckoMediaPluginServiceParent,
                             GeckoMediaPluginService,
-                            mozIGeckoMediaPluginChromeService)
+                            mozIGeckoMediaPluginChromeService,
+                            nsIAsyncShutdownBlocker)
 
 GeckoMediaPluginServiceParent::GeckoMediaPluginServiceParent()
   : mShuttingDown(false)
 #ifdef MOZ_CRASHREPORTER
   , mAsyncShutdownPluginStatesMutex("GeckoMediaPluginService::mAsyncShutdownPluginStatesMutex")
 #endif
   , mScannedPluginOnDisk(false)
   , mWaitingForPluginsSyncShutdown(false)
   , mInitPromiseMonitor("GeckoMediaPluginServiceParent::mInitPromiseMonitor")
   , mLoadPluginsFromDiskComplete(false)
+  , mServiceUserCount(0)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mInitPromise.SetMonitor(&mInitPromiseMonitor);
 }
 
 GeckoMediaPluginServiceParent::~GeckoMediaPluginServiceParent()
 {
   MOZ_ASSERT(mPlugins.IsEmpty());
@@ -1130,17 +1134,17 @@ GeckoMediaPluginServiceParent::RemoveOnG
   }
 
   // Plugin destruction can modify |mPlugins|. Put them aside for now and
   // destroy them once we're done with |mPlugins|.
   nsTArray<RefPtr<GMPParent>> deadPlugins;
 
   bool inUse = false;
   MutexAutoLock lock(mMutex);
-  for (size_t i = mPlugins.Length() - 1; i < mPlugins.Length(); i--) {
+  for (size_t i = mPlugins.Length(); i-- > 0; ) {
     nsCOMPtr<nsIFile> pluginpath = mPlugins[i]->GetDirectory();
     bool equals;
     if (NS_FAILED(directory->Equals(pluginpath, &equals)) || !equals) {
       continue;
     }
 
     RefPtr<GMPParent> gmp = mPlugins[i];
     if (aDeleteFromDisk && gmp->State() != GMPStateNotLoaded) {
@@ -1833,16 +1837,71 @@ GeckoMediaPluginServiceParent::ForgetThi
       this, &GeckoMediaPluginServiceParent::ForgetThisSiteOnGMPThread,
       NS_ConvertUTF16toUTF8(aSite), aPattern));
 }
 
 static bool IsNodeIdValid(GMPParent* aParent) {
   return !aParent->GetNodeId().IsEmpty();
 }
 
+static nsCOMPtr<nsIAsyncShutdownClient>
+GetShutdownBarrier()
+{
+  nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown();
+  MOZ_RELEASE_ASSERT(svc);
+
+  nsCOMPtr<nsIAsyncShutdownClient> barrier;
+  nsresult rv = svc->GetXpcomWillShutdown(getter_AddRefs(barrier));
+
+  MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
+  MOZ_RELEASE_ASSERT(barrier);
+  return barrier.forget();
+}
+
+NS_IMETHODIMP
+GeckoMediaPluginServiceParent::GetName(nsAString& aName)
+{
+  aName = NS_LITERAL_STRING("GeckoMediaPluginServiceParent: shutdown");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+GeckoMediaPluginServiceParent::GetState(nsIPropertyBag**)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+GeckoMediaPluginServiceParent::BlockShutdown(nsIAsyncShutdownClient*)
+{
+  return NS_OK;
+}
+
+void
+GeckoMediaPluginServiceParent::ServiceUserCreated()
+{
+  MOZ_ASSERT(mServiceUserCount >= 0);
+  if (++mServiceUserCount == 1) {
+    nsresult rv = GetShutdownBarrier()->AddBlocker(
+      this, NS_LITERAL_STRING(__FILE__), __LINE__,
+      NS_LITERAL_STRING("GeckoMediaPluginServiceParent shutdown"));
+    MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
+  }
+}
+
+void
+GeckoMediaPluginServiceParent::ServiceUserDestroyed()
+{
+  MOZ_ASSERT(mServiceUserCount > 0);
+  if (--mServiceUserCount == 0) {
+    nsresult rv = GetShutdownBarrier()->RemoveBlocker(this);
+    MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
+  }
+}
+
 void
 GeckoMediaPluginServiceParent::ClearStorage()
 {
   MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
   LOGD(("%s::%s", __CLASS__, __FUNCTION__));
 
   // Kill plugins with valid nodeIDs.
   KillPlugins(mPlugins, mMutex, &IsNodeIdValid);
@@ -1872,16 +1931,19 @@ GeckoMediaPluginServiceParent::GetById(u
       return do_AddRef(gmp);
     }
   }
   return nullptr;
 }
 
 GMPServiceParent::~GMPServiceParent()
 {
+  NS_DispatchToMainThread(
+    NewRunnableMethod(mService.get(),
+                      &GeckoMediaPluginServiceParent::ServiceUserDestroyed));
 }
 
 bool
 GMPServiceParent::RecvSelectGMP(const nsCString& aNodeId,
                                 const nsCString& aAPI,
                                 nsTArray<nsCString>&& aTags,
                                 uint32_t* aOutPluginId,
                                 nsresult* aOutRv)
@@ -1971,19 +2033,48 @@ public:
   {
     return NS_OK;
   }
 
 private:
   nsAutoPtr<GMPServiceParent> mToDelete;
 };
 
+void GMPServiceParent::CloseTransport(Monitor* aSyncMonitor, bool* aCompleted)
+{
+  MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
+
+  MonitorAutoLock lock(*aSyncMonitor);
+
+  // This deletes the transport.
+  SetTransport(nullptr);
+
+  *aCompleted = true;
+  lock.NotifyAll();
+}
+
 void
 GMPServiceParent::ActorDestroy(ActorDestroyReason aWhy)
 {
+  Monitor monitor("DeleteGMPServiceParent");
+  bool completed = false;
+
+  // Make sure the IPC channel is closed before destroying mToDelete.
+  MonitorAutoLock lock(monitor);
+  RefPtr<Runnable> task =
+    NewNonOwningRunnableMethod<Monitor*, bool*>(this,
+                                                &GMPServiceParent::CloseTransport,
+                                                &monitor,
+                                                &completed);
+  XRE_GetIOMessageLoop()->PostTask(Move(task.forget()));
+
+  while (!completed) {
+    lock.Wait();
+  }
+
   NS_DispatchToCurrentThread(new DeleteGMPServiceParent(this));
 }
 
 class OpenPGMPServiceParent : public mozilla::Runnable
 {
 public:
   OpenPGMPServiceParent(GMPServiceParent* aGMPServiceParent,
                         mozilla::ipc::Transport* aTransport,
@@ -2012,22 +2103,27 @@ private:
 
 /* static */
 PGMPServiceParent*
 GMPServiceParent::Create(Transport* aTransport, ProcessId aOtherPid)
 {
   RefPtr<GeckoMediaPluginServiceParent> gmp =
     GeckoMediaPluginServiceParent::GetSingleton();
 
-  nsAutoPtr<GMPServiceParent> serviceParent(new GMPServiceParent(gmp));
+  if (gmp->mShuttingDown) {
+    // Shutdown is initiated. There is no point creating a new actor.
+    return nullptr;
+  }
 
   nsCOMPtr<nsIThread> gmpThread;
   nsresult rv = gmp->GetThread(getter_AddRefs(gmpThread));
   NS_ENSURE_SUCCESS(rv, nullptr);
 
+  nsAutoPtr<GMPServiceParent> serviceParent(new GMPServiceParent(gmp));
+
   bool ok;
   rv = gmpThread->Dispatch(new OpenPGMPServiceParent(serviceParent,
                                                      aTransport,
                                                      aOtherPid, &ok),
                            NS_DISPATCH_SYNC);
   if (NS_FAILED(rv) || !ok) {
     return nullptr;
   }
--- a/dom/media/gmp/GMPServiceParent.h
+++ b/dom/media/gmp/GMPServiceParent.h
@@ -7,37 +7,40 @@
 #define GMPServiceParent_h_
 
 #include "GMPService.h"
 #include "mozilla/gmp/PGMPServiceParent.h"
 #include "mozIGeckoMediaPluginChromeService.h"
 #include "nsClassHashtable.h"
 #include "nsDataHashtable.h"
 #include "mozilla/Atomics.h"
+#include "nsIAsyncShutdown.h"
 #include "nsThreadUtils.h"
 #include "mozilla/MozPromise.h"
 #include "GMPStorage.h"
 
 template <class> struct already_AddRefed;
 
 namespace mozilla {
 namespace gmp {
 
 class GMPParent;
 
 class GeckoMediaPluginServiceParent final : public GeckoMediaPluginService
                                           , public mozIGeckoMediaPluginChromeService
+                                          , public nsIAsyncShutdownBlocker
 {
 public:
   static already_AddRefed<GeckoMediaPluginServiceParent> GetSingleton();
 
   GeckoMediaPluginServiceParent();
   nsresult Init() override;
 
   NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSIASYNCSHUTDOWNBLOCKER
 
   // mozIGeckoMediaPluginService
   NS_IMETHOD GetPluginVersionForAPI(const nsACString& aAPI,
                                     nsTArray<nsCString>* aTags,
                                     bool* aHasPlugin,
                                     nsACString& aOutVersion) override;
   NS_IMETHOD GetNodeId(const nsAString& aOrigin,
                        const nsAString& aTopLevelOrigin,
@@ -60,16 +63,20 @@ public:
 
   // GMP thread access only
   bool IsShuttingDown();
 
   already_AddRefed<GMPStorage> GetMemoryStorageFor(const nsACString& aNodeId);
   nsresult ForgetThisSiteNative(const nsAString& aSite,
                                 const mozilla::OriginAttributesPattern& aPattern);
 
+  // Notifies that some user of this class is created/destroyed.
+  void ServiceUserCreated();
+  void ServiceUserDestroyed();
+
 private:
   friend class GMPServiceParent;
 
   virtual ~GeckoMediaPluginServiceParent();
 
   void ClearStorage();
 
   already_AddRefed<GMPParent> SelectPluginForAPI(const nsACString& aNodeId,
@@ -212,29 +219,34 @@ private:
   // Synchronization for barrier that ensures we've loaded GMPs from
   // MOZ_GMP_PATH before allowing GetContentParentFrom() to proceed.
   Monitor mInitPromiseMonitor;
   MozPromiseHolder<GenericPromise> mInitPromise;
   bool mLoadPluginsFromDiskComplete;
 
   // Hashes nodeId to the hashtable of storage for that nodeId.
   nsRefPtrHashtable<nsCStringHashKey, GMPStorage> mTempGMPStorage;
+
+  // Tracks how many users are running (on the GMP thread). Only when this count
+  // drops to 0 can we safely shut down the thread.
+  MainThreadOnly<int32_t> mServiceUserCount;
 };
 
 nsresult ReadSalt(nsIFile* aPath, nsACString& aOutData);
 bool MatchOrigin(nsIFile* aPath,
                  const nsACString& aSite,
                  const mozilla::OriginAttributesPattern& aPattern);
 
 class GMPServiceParent final : public PGMPServiceParent
 {
 public:
   explicit GMPServiceParent(GeckoMediaPluginServiceParent* aService)
     : mService(aService)
   {
+    mService->ServiceUserCreated();
   }
   virtual ~GMPServiceParent();
 
   bool RecvGetGMPNodeId(const nsString& aOrigin,
                         const nsString& aTopLevelOrigin,
                         const nsString& aGMPName,
                         const bool& aInPrivateBrowsing,
                         nsCString* aID) override;
@@ -254,15 +266,17 @@ public:
 
   bool RecvLaunchGMP(const uint32_t& aPluginId,
                      nsTArray<ProcessId>&& aAlreadyBridgedTo,
                      ProcessId* aOutID,
                      nsCString* aOutDisplayName,
                      nsresult* aOutRv) override;
 
 private:
+  void CloseTransport(Monitor* aSyncMonitor, bool* aCompleted);
+
   RefPtr<GeckoMediaPluginServiceParent> mService;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // GMPServiceParent_h_
--- a/dom/media/platforms/android/AndroidDecoderModule.cpp
+++ b/dom/media/platforms/android/AndroidDecoderModule.cpp
@@ -24,16 +24,43 @@
     mozilla::LogLevel::Debug, ("AndroidDecoderModule(%p)::%s: " arg, \
       this, __func__, ##__VA_ARGS__))
 
 using namespace mozilla;
 using namespace mozilla::gl;
 using namespace mozilla::java::sdk;
 using media::TimeUnit;
 
+namespace {
+  template<class T>
+  mozilla::jni::ByteArray::LocalRef
+  CreateAndInitJByteArray(const T& data, jsize length)
+  {
+    JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
+    jbyteArray result = jenv->NewByteArray(length);
+    MOZ_CATCH_JNI_EXCEPTION(jenv);
+    jenv->SetByteArrayRegion(result, 0, length, reinterpret_cast<const jbyte*>(const_cast<T>(data)));
+    MOZ_CATCH_JNI_EXCEPTION(jenv);
+    return mozilla::jni::ByteArray::LocalRef::Adopt(jenv, result);
+  }
+
+  template<class T>
+  mozilla::jni::IntArray::LocalRef
+  CreateAndInitJIntArray(const T& data, jsize length)
+  {
+    JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
+    jintArray result = jenv->NewIntArray(length);
+    MOZ_CATCH_JNI_EXCEPTION(jenv);
+    jenv->SetIntArrayRegion(result, 0, length, reinterpret_cast<const jint*>(const_cast<T>(data)));
+    MOZ_CATCH_JNI_EXCEPTION(jenv);
+    return mozilla::jni::IntArray::LocalRef::Adopt(jenv, result);
+  }
+}
+
+
 namespace mozilla {
 
 mozilla::LazyLogModule sAndroidDecoderModuleLog("AndroidDecoderModule");
 
 static const char*
 TranslateMimeType(const nsACString& aMimeType)
 {
   if (VPXDecoder::IsVPX(aMimeType, VPXDecoder::VP8)) {
@@ -51,16 +78,73 @@ GetFeatureStatus(int32_t aFeature)
   int32_t status = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
   nsCString discardFailureId;
   if (!gfxInfo || NS_FAILED(gfxInfo->GetFeatureStatus(aFeature, discardFailureId, &status))) {
     return false;
   }
   return status == nsIGfxInfo::FEATURE_STATUS_OK;
 };
 
+CryptoInfo::LocalRef
+GetCryptoInfoFromSample(const MediaRawData* aSample)
+{
+  auto& cryptoObj = aSample->mCrypto;
+
+  if (!cryptoObj.mValid) {
+    return nullptr;
+  }
+
+  CryptoInfo::LocalRef cryptoInfo;
+  nsresult rv = CryptoInfo::New(&cryptoInfo);
+  NS_ENSURE_SUCCESS(rv, nullptr);
+
+  uint32_t numSubSamples =
+    std::min<uint32_t>(cryptoObj.mPlainSizes.Length(), cryptoObj.mEncryptedSizes.Length());
+
+  uint32_t totalSubSamplesSize = 0;
+  for (auto& size : cryptoObj.mEncryptedSizes) {
+    totalSubSamplesSize += size;
+  }
+
+  // mPlainSizes is uint16_t, need to transform to uint32_t first.
+  nsTArray<uint32_t> plainSizes;
+  for (auto& size : cryptoObj.mPlainSizes) {
+    totalSubSamplesSize += size;
+    plainSizes.AppendElement(size);
+  }
+
+  uint32_t codecSpecificDataSize = aSample->Size() - totalSubSamplesSize;
+  // Size of codec specific data("CSD") for Android MediaCodec usage should be
+  // included in the 1st plain size.
+  plainSizes[0] += codecSpecificDataSize;
+
+  static const int kExpectedIVLength = 16;
+  auto tempIV(cryptoObj.mIV);
+  auto tempIVLength = tempIV.Length();
+  MOZ_ASSERT(tempIVLength <= kExpectedIVLength);
+  for (size_t i = tempIVLength; i < kExpectedIVLength; i++) {
+    // Padding with 0
+    tempIV.AppendElement(0);
+  }
+
+  auto numBytesOfPlainData = CreateAndInitJIntArray(&plainSizes[0], plainSizes.Length());
+  auto numBytesOfEncryptedData = CreateAndInitJIntArray(&cryptoObj.mEncryptedSizes[0],
+                                                        cryptoObj.mEncryptedSizes.Length());
+  auto iv = CreateAndInitJByteArray(&tempIV[0], tempIV.Length());
+  auto keyId = CreateAndInitJByteArray(&cryptoObj.mKeyId[0], cryptoObj.mKeyId.Length());
+  cryptoInfo->Set(numSubSamples,
+                  numBytesOfPlainData,
+                  numBytesOfEncryptedData,
+                  keyId,
+                  iv,
+                  MediaCodec::CRYPTO_MODE_AES_CTR);
+
+  return cryptoInfo;
+}
+
 bool
 AndroidDecoderModule::SupportsMimeType(const nsACString& aMimeType,
                                        DecoderDoctorDiagnostics* aDiagnostics) const
 {
   if (!AndroidBridge::Bridge() ||
       AndroidBridge::Bridge()->GetAPIVersion() < 16) {
     return false;
   }
--- a/dom/media/platforms/android/MediaCodecDataDecoder.cpp
+++ b/dom/media/platforms/android/MediaCodecDataDecoder.cpp
@@ -389,18 +389,25 @@ MediaCodecDataDecoder::QueueSample(const
   void* directBuffer = frame.GetEnv()->GetDirectBufferAddress(buffer.Get());
 
   MOZ_ASSERT(frame.GetEnv()->GetDirectBufferCapacity(buffer.Get()) >=
              aSample->Size(),
              "Decoder buffer is not large enough for sample");
 
   PodCopy(static_cast<uint8_t*>(directBuffer), aSample->Data(), aSample->Size());
 
-  res = mDecoder->QueueInputBuffer(inputIndex, 0, aSample->Size(),
-                                   aSample->mTime, 0);
+  CryptoInfo::LocalRef cryptoInfo = GetCryptoInfoFromSample(aSample);
+  if (cryptoInfo) {
+    res = mDecoder->QueueSecureInputBuffer(inputIndex, 0, cryptoInfo,
+                                           aSample->mTime, 0);
+  } else {
+    res = mDecoder->QueueInputBuffer(inputIndex, 0, aSample->Size(),
+                                     aSample->mTime, 0);
+  }
+
   if (NS_FAILED(res)) {
     return res;
   }
 
   mDurations.push_back(TimeUnit::FromMicroseconds(aSample->mDuration));
   return NS_OK;
 }
 
--- a/dom/media/platforms/android/RemoteDataDecoder.cpp
+++ b/dom/media/platforms/android/RemoteDataDecoder.cpp
@@ -437,17 +437,17 @@ RemoteDataDecoder::Flush()
 void
 RemoteDataDecoder::Drain()
 {
   BufferInfo::LocalRef bufferInfo;
   nsresult rv = BufferInfo::New(&bufferInfo);
   NS_ENSURE_SUCCESS_VOID(rv);
   bufferInfo->Set(0, 0, -1, MediaCodec::BUFFER_FLAG_END_OF_STREAM);
 
-  mJavaDecoder->Input(nullptr, bufferInfo);
+  mJavaDecoder->Input(nullptr, bufferInfo, nullptr);
 }
 
 void
 RemoteDataDecoder::Shutdown()
 {
   LOG("");
   MOZ_ASSERT(mJavaDecoder && mJavaCallbacks);
 
@@ -478,12 +478,12 @@ RemoteDataDecoder::Input(MediaRawData* a
   BufferInfo::LocalRef bufferInfo;
   nsresult rv = BufferInfo::New(&bufferInfo);
   if (NS_FAILED(rv)) {
     mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
     return;
   }
   bufferInfo->Set(0, aSample->Size(), aSample->mTime, 0);
 
-  mJavaDecoder->Input(bytes, bufferInfo);
+  mJavaDecoder->Input(bytes, bufferInfo, GetCryptoInfoFromSample(aSample));
 }
 
 } // mozilla
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -753,35 +753,47 @@ function PeerConnectionWrapper(label, co
   this.audioElementsOnly = false;
 
   this.expectedLocalTrackInfoById = {};
   this.expectedRemoteTrackInfoById = {};
   this.observedRemoteTrackInfoById = {};
 
   this.disableRtpCountChecking = false;
 
+  this.iceConnectedResolve;
+  this.iceConnectedReject;
+  this.iceConnected = new Promise((resolve, reject) => {
+    this.iceConnectedResolve = resolve;
+    this.iceConnectedReject = reject;
+  });
   this.iceCheckingRestartExpected = false;
   this.iceCheckingIceRollbackExpected = false;
 
   info("Creating " + this);
   this._pc = new RTCPeerConnection(this.configuration);
 
   /**
    * Setup callback handlers
    */
   // This allows test to register their own callbacks for ICE connection state changes
   this.ice_connection_callbacks = {};
 
   this._pc.oniceconnectionstatechange = e => {
     isnot(typeof this._pc.iceConnectionState, "undefined",
           "iceConnectionState should not be undefined");
-    info(this + ": oniceconnectionstatechange fired, new state is: " + this._pc.iceConnectionState);
+    var iceState = this._pc.iceConnectionState;
+    info(this + ": oniceconnectionstatechange fired, new state is: " + iceState);
     Object.keys(this.ice_connection_callbacks).forEach(name => {
       this.ice_connection_callbacks[name]();
     });
+    if (iceState === "connected") {
+      this.iceConnectedResolve();
+    } else if (iceState === "failed") {
+      this.iceConnectedReject();
+    }
   };
 
   createOneShotEventWrapper(this, this._pc, 'datachannel');
   this._pc.addEventListener('datachannel', e => {
     var wrapper = new DataChannelWrapper(e.channel, this);
     this.dataChannels.push(wrapper);
   });
 
@@ -1197,55 +1209,16 @@ PeerConnectionWrapper.prototype = {
       // race of the Promises around our test steps.
       // Note: as long as we are queuing ICE candidates until the success
       //       of sRD() this should never ever happen.
       ok(false, this + " adding ICE candidate failed with: " + e.message)
     );
   },
 
   /**
-   * Returns if the ICE the connection state is "connected".
-   *
-   * @returns {boolean} True if the connection state is "connected", otherwise false.
-   */
-  isIceConnected : function() {
-    info(this + ": iceConnectionState = " + this.iceConnectionState);
-    return this.iceConnectionState === "connected";
-  },
-
-  /**
-   * Returns if the ICE the connection state is "checking".
-   *
-   * @returns {boolean} True if the connection state is "checking", otherwise false.
-   */
-  isIceChecking : function() {
-    return this.iceConnectionState === "checking";
-  },
-
-  /**
-   * Returns if the ICE the connection state is "new".
-   *
-   * @returns {boolean} True if the connection state is "new", otherwise false.
-   */
-  isIceNew : function() {
-    return this.iceConnectionState === "new";
-  },
-
-  /**
-   * Checks if the ICE connection state still waits for a connection to get
-   * established.
-   *
-   * @returns {boolean} True if the connection state is "checking" or "new",
-   *  otherwise false.
-   */
-  isIceConnectionPending : function() {
-    return (this.isIceChecking() || this.isIceNew());
-  },
-
-  /**
    * Registers a callback for the ICE connection state change and
    * appends the new state to an array for logging it later.
    */
   logIceConnectionState: function() {
     this.iceConnectionLog = [this._pc.iceConnectionState];
     this.ice_connection_callbacks.logIceStatus = () => {
       var newstate = this._pc.iceConnectionState;
       var oldstate = this.iceConnectionLog[this.iceConnectionLog.length - 1]
@@ -1266,34 +1239,35 @@ PeerConnectionWrapper.prototype = {
       } else {
         ok(false, this + ": old ICE state " + oldstate + " missing in ICE transition array");
       }
       this.iceConnectionLog.push(newstate);
     };
   },
 
   /**
-   * Registers a callback for the ICE connection state change and
-   * reports success (=connected) or failure via the callbacks.
-   * States "new" and "checking" are ignored.
+   * Resets the ICE connected Promise and allows ICE connection state monitoring
+   * to go backwards to 'checking'.
+   */
+  expectIceChecking : function() {
+    this.iceCheckingRestartExpected = true;
+    this.iceConnected = new Promise((resolve, reject) => {
+      this.iceConnectedResolve = resolve;
+      this.iceConnectedReject = reject;
+    });
+  },
+
+  /**
+   * Waits for ICE to either connect or fail.
    *
    * @returns {Promise}
    *          resolves when connected, rejects on failure
    */
   waitForIceConnected : function() {
-    return new Promise((resolve, reject) =>
-        this.ice_connection_callbacks.waitForIceConnected = () => {
-      if (this.isIceConnected()) {
-        delete this.ice_connection_callbacks.waitForIceConnected;
-        resolve();
-      } else if (!this.isIceConnectionPending()) {
-        delete this.ice_connection_callbacks.waitForIceConnected;
-        reject(new Error('ICE failed'));
-      }
-    });
+    return this.iceConnected;
   },
 
   /**
    * Setup a onicecandidate handler
    *
    * @param {object} test
    *        A PeerConnectionTest object to which the ice candidates gets
    *        forwarded.
--- a/dom/media/tests/mochitest/templates.js
+++ b/dom/media/tests/mochitest/templates.js
@@ -57,39 +57,16 @@ function dumpSdp(test) {
   if ((test.pcLocal) && (test.pcRemote) &&
     (typeof test.pcRemote.setLocalDescDate !== 'undefined') &&
     (typeof test.pcRemote.setLocalDescStableEventDate !== 'undefined')) {
     var delta = deltaSeconds(test.pcRemote.setLocalDescDate, test.pcRemote.setLocalDescStableEventDate);
     dump("Delay between pcRemote.setLocal <-> pcRemote.signalingStateStable: " + delta + "\n");
   }
 }
 
-function waitForIceConnected(test, pc) {
-  if (!pc.iceCheckingRestartExpected) {
-    if (pc.isIceConnected()) {
-      info(pc + ": ICE connection state log: " + pc.iceConnectionLog);
-      ok(true, pc + ": ICE is in connected state");
-      return Promise.resolve();
-    }
-
-    if (!pc.isIceConnectionPending()) {
-      dumpSdp(test);
-      var details = pc + ": ICE is already in bad state: " + pc.iceConnectionState;
-      ok(false, details);
-      return Promise.reject(new Error(details));
-    }
-  }
-
-  return pc.waitForIceConnected()
-    .then(() => {
-      info(pc + ": ICE connection state log: " + pc.iceConnectionLog);
-      ok(pc.isIceConnected(), pc + ": ICE switched to 'connected' state");
-    });
-}
-
 // We need to verify that at least one candidate has been (or will be) gathered.
 function waitForAnIceCandidate(pc) {
   return new Promise(resolve => {
     if (!pc.localRequiresTrickleIce ||
         pc._local_ice_candidates.length > 0) {
       resolve();
     } else {
       // In some circumstances, especially when both PCs are on the same
@@ -394,21 +371,27 @@ var commandsPeerConnectionOfferAnswer = 
   },
 
   function PC_LOCAL_CHECK_CAN_TRICKLE_SYNC(test) {
     is(test.pcLocal._pc.canTrickleIceCandidates, true,
        "Local thinks that remote can trickle");
   },
 
   function PC_LOCAL_WAIT_FOR_ICE_CONNECTED(test) {
-    return waitForIceConnected(test, test.pcLocal);
+    return test.pcLocal.waitForIceConnected()
+    .then(() => {
+      info(test.pcLocal + ": ICE connection state log: " + test.pcLocal.iceConnectionLog);
+    });
   },
 
   function PC_REMOTE_WAIT_FOR_ICE_CONNECTED(test) {
-    return waitForIceConnected(test, test.pcRemote);
+    return test.pcRemote.waitForIceConnected()
+    .then(() => {
+      info(test.pcRemote + ": ICE connection state log: " + test.pcRemote.iceConnectionLog);
+    });
   },
 
   function PC_LOCAL_VERIFY_ICE_GATHERING(test) {
     return waitForAnIceCandidate(test.pcLocal);
   },
 
   function PC_REMOTE_VERIFY_ICE_GATHERING(test) {
     return waitForAnIceCandidate(test.pcRemote);
--- a/dom/media/tests/mochitest/test_peerConnection_addDataChannelNoBundle.html
+++ b/dom/media/tests/mochitest/test_peerConnection_addDataChannelNoBundle.html
@@ -15,20 +15,20 @@
   runNetworkTest(function (options) {
     options = options || { };
     options.bundle = false;
     test = new PeerConnectionTest(options);
     addRenegotiation(test.chain,
                      commandsCreateDataChannel.concat(
                        [
                          function PC_LOCAL_EXPECT_ICE_CHECKING(test) {
-                           test.pcLocal.iceCheckingRestartExpected = true;
+                           test.pcLocal.expectIceChecking();
                          },
                          function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
-                           test.pcRemote.iceCheckingRestartExpected = true;
+                           test.pcRemote.expectIceChecking();
                          },
                        ]
                       ),
                      commandsCheckDataChannel);
 
     // Insert before the second PC_LOCAL_WAIT_FOR_MEDIA_FLOW
     test.chain.insertBefore('PC_LOCAL_WAIT_FOR_MEDIA_FLOW',
                             commandsWaitForDataChannel,
--- a/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStreamNoBundle.html
+++ b/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStreamNoBundle.html
@@ -18,21 +18,21 @@
     test = new PeerConnectionTest(options);
     addRenegotiation(test.chain,
       [
         function PC_LOCAL_ADD_SECOND_STREAM(test) {
           test.setMediaConstraints([{audio: true}, {audio: true}],
                                    [{audio: true}]);
           // Since this is a NoBundle variant, adding a track will cause us to
           // go back to checking.
-          test.pcLocal.iceCheckingRestartExpected = true;
+          test.pcLocal.expectIceChecking();
           return test.pcLocal.getAllUserMedia([{audio: true}]);
         },
         function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
-          test.pcRemote.iceCheckingRestartExpected = true;
+          test.pcRemote.expectIceChecking();
         },
       ]
     );
 
     // TODO(bug 1093835): figure out how to verify if media flows through the new stream
     test.setMediaConstraints([{audio: true}], [{audio: true}]);
     test.run();
   });
--- a/dom/media/tests/mochitest/test_peerConnection_addSecondVideoStreamNoBundle.html
+++ b/dom/media/tests/mochitest/test_peerConnection_addSecondVideoStreamNoBundle.html
@@ -18,21 +18,21 @@
     test = new PeerConnectionTest(options);
     addRenegotiation(test.chain,
       [
         function PC_LOCAL_ADD_SECOND_STREAM(test) {
           test.setMediaConstraints([{video: true}, {video: true}],
                                    [{video: true}]);
           // Since this is a NoBundle variant, adding a track will cause us to
           // go back to checking.
-          test.pcLocal.iceCheckingRestartExpected = true;
+          test.pcLocal.expectIceChecking();
           return test.pcLocal.getAllUserMedia([{video: true}]);
         },
         function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
-          test.pcRemote.iceCheckingRestartExpected = true;
+          test.pcRemote.expectIceChecking();
         },
       ]
     );
 
     // TODO(bug 1093835): figure out how to verify if media flows through the new stream
     test.setMediaConstraints([{video: true}], [{video: true}]);
     test.run();
   });
--- a/dom/media/tests/mochitest/test_peerConnection_restartIce.html
+++ b/dom/media/tests/mochitest/test_peerConnection_restartIce.html
@@ -17,20 +17,20 @@
 
     addRenegotiation(test.chain,
       [
         // causes a full, normal ice restart
         function PC_LOCAL_SET_OFFER_OPTION(test) {
           test.setOfferOptions({ iceRestart: true });
         },
         function PC_LOCAL_EXPECT_ICE_CHECKING(test) {
-          test.pcLocal.iceCheckingRestartExpected = true;
+          test.pcLocal.expectIceChecking();
         },
         function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
-          test.pcRemote.iceCheckingRestartExpected = true;
+          test.pcRemote.expectIceChecking();
         }
       ]
     );
 
     test.setMediaConstraints([{audio: true}, {video: true}],
                              [{audio: true}, {video: true}]);
     test.run();
   });
--- a/dom/media/tests/mochitest/test_peerConnection_restartIceLocalAndRemoteRollback.html
+++ b/dom/media/tests/mochitest/test_peerConnection_restartIceLocalAndRemoteRollback.html
@@ -70,20 +70,20 @@
         function PC_LOCAL_WAIT_FOR_END_OF_TRICKLE(test) {
           return test.pcLocal.endOfTrickleIce;
         },
         function PC_REMOTE_WAIT_FOR_END_OF_TRICKLE(test) {
           return test.pcRemote.endOfTrickleIce;
         },
 
         function PC_LOCAL_EXPECT_ICE_CHECKING(test) {
-          test.pcLocal.iceCheckingRestartExpected = true;
+          test.pcLocal.expectIceChecking();
         },
         function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
-          test.pcRemote.iceCheckingRestartExpected = true;
+          test.pcRemote.expectIceChecking();
         }
       ],
       1 // Replaces after second PC_REMOTE_CREATE_ANSWER
     );
     test.chain.append(commandsPeerConnectionOfferAnswer);
 
     // for now, only use one stream, because rollback doesn't seem to
     // like multiple streams.  See bug 1259465.
--- a/dom/media/tests/mochitest/test_peerConnection_restartIceLocalRollback.html
+++ b/dom/media/tests/mochitest/test_peerConnection_restartIceLocalRollback.html
@@ -48,20 +48,20 @@
                                           sdp: ""}),
               STABLE);
         },
         // Rolling back should shut down gathering
         function PC_LOCAL_WAIT_FOR_END_OF_TRICKLE(test) {
           return test.pcLocal.endOfTrickleIce;
         },
         function PC_LOCAL_EXPECT_ICE_CHECKING(test) {
-          test.pcLocal.iceCheckingRestartExpected = true;
+          test.pcLocal.expectIceChecking();
         },
         function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
-          test.pcRemote.iceCheckingRestartExpected = true;
+          test.pcRemote.expectIceChecking();
         }
       ]
     );
 
     // for now, only use one stream, because rollback doesn't seem to
     // like multiple streams.  See bug 1259465.
     test.setMediaConstraints([{audio: true}],
                              [{audio: true}]);
--- a/dom/media/tests/mochitest/test_peerConnection_restartIceNoBundle.html
+++ b/dom/media/tests/mochitest/test_peerConnection_restartIceNoBundle.html
@@ -19,20 +19,20 @@
 
     addRenegotiation(test.chain,
       [
         // causes a full, normal ice restart
         function PC_LOCAL_SET_OFFER_OPTION(test) {
           test.setOfferOptions({ iceRestart: true });
         },
         function PC_LOCAL_EXPECT_ICE_CHECKING(test) {
-          test.pcLocal.iceCheckingRestartExpected = true;
+          test.pcLocal.expectIceChecking();
         },
         function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
-          test.pcRemote.iceCheckingRestartExpected = true;
+          test.pcRemote.expectIceChecking();
         }
       ]
     );
 
     test.setMediaConstraints([{audio: true}, {video: true}],
                              [{audio: true}, {video: true}]);
     test.run();
   });
--- a/dom/media/tests/mochitest/test_peerConnection_restartIceNoBundleNoRtcpMux.html
+++ b/dom/media/tests/mochitest/test_peerConnection_restartIceNoBundleNoRtcpMux.html
@@ -20,20 +20,20 @@
 
     addRenegotiation(test.chain,
       [
         // causes a full, normal ice restart
         function PC_LOCAL_SET_OFFER_OPTION(test) {
           test.setOfferOptions({ iceRestart: true });
         },
         function PC_LOCAL_EXPECT_ICE_CHECKING(test) {
-          test.pcLocal.iceCheckingRestartExpected = true;
+          test.pcLocal.expectIceChecking();
         },
         function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
-          test.pcRemote.iceCheckingRestartExpected = true;
+          test.pcRemote.expectIceChecking();
         }
       ]
     );
 
     test.setMediaConstraints([{audio: true}, {video: true}],
                              [{audio: true}, {video: true}]);
     test.run();
   });
--- a/dom/media/tests/mochitest/test_peerConnection_restartIceNoRtcpMux.html
+++ b/dom/media/tests/mochitest/test_peerConnection_restartIceNoRtcpMux.html
@@ -19,20 +19,20 @@
 
     addRenegotiation(test.chain,
       [
         // causes a full, normal ice restart
         function PC_LOCAL_SET_OFFER_OPTION(test) {
           test.setOfferOptions({ iceRestart: true });
         },
         function PC_LOCAL_EXPECT_ICE_CHECKING(test) {
-          test.pcLocal.iceCheckingRestartExpected = true;
+          test.pcLocal.expectIceChecking();
         },
         function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
-          test.pcRemote.iceCheckingRestartExpected = true;
+          test.pcRemote.expectIceChecking();
         }
       ]
     );
 
     test.setMediaConstraints([{audio: true}, {video: true}],
                              [{audio: true}, {video: true}]);
     test.run();
   });
--- a/dom/xbl/nsXBLPrototypeHandler.cpp
+++ b/dom/xbl/nsXBLPrototypeHandler.cpp
@@ -638,34 +638,38 @@ struct keyCodeData {
 };
 
 // All of these must be uppercase, since the function below does
 // case-insensitive comparison by converting to uppercase.
 // XXX: be sure to check this periodically for new symbol additions!
 static const keyCodeData gKeyCodes[] = {
 
 #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) \
-  { #aDOMKeyName, sizeof(#aDOMKeyName) - 1, aDOMKeyCode }
+  { #aDOMKeyName, sizeof(#aDOMKeyName) - 1, aDOMKeyCode },
 #include "mozilla/VirtualKeyCodeList.h"
 #undef NS_DEFINE_VK
+
+  { nullptr, 0, 0 }
 };
 
 int32_t nsXBLPrototypeHandler::GetMatchingKeyCode(const nsAString& aKeyName)
 {
   nsAutoCString keyName;
   keyName.AssignWithConversion(aKeyName);
   ToUpperCase(keyName); // We want case-insensitive comparison with data
                         // stored as uppercase.
 
   uint32_t keyNameLength = keyName.Length();
   const char* keyNameStr = keyName.get();
-  for (uint16_t i = 0; i < (sizeof(gKeyCodes) / sizeof(gKeyCodes[0])); ++i)
+  for (uint16_t i = 0; i < ArrayLength(gKeyCodes) - 1; ++i) {
     if (keyNameLength == gKeyCodes[i].strlength &&
-        !nsCRT::strcmp(gKeyCodes[i].str, keyNameStr))
+        !nsCRT::strcmp(gKeyCodes[i].str, keyNameStr)) {
       return gKeyCodes[i].keycode;
+    }
+  }
 
   return 0;
 }
 
 int32_t nsXBLPrototypeHandler::KeyToMask(int32_t key)
 {
   switch (key)
   {
--- a/editor/libeditor/tests/mochitest.ini
+++ b/editor/libeditor/tests/mochitest.ini
@@ -114,17 +114,17 @@ skip-if = toolkit == 'android' #bug 9577
 [test_bug638596.html]
 [test_bug640321.html]
 skip-if = android_version == '18' # bug 1147989
 [test_bug641466.html]
 [test_bug645914.html]
 [test_bug668599.html]
 [test_bug674770-1.html]
 subsuite = clipboard
-skip-if = toolkit == 'android' || (os == 'linux' && e10s && (debug||asan)) # Bug 972110
+skip-if = toolkit == 'android'
 [test_bug674770-2.html]
 subsuite = clipboard
 skip-if = toolkit == 'android'
 [test_bug674861.html]
 [test_bug676401.html]
 [test_bug677752.html]
 [test_bug681229.html]
 subsuite = clipboard
--- a/editor/libeditor/tests/test_bug674770-1.html
+++ b/editor/libeditor/tests/test_bug674770-1.html
@@ -19,51 +19,68 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a href="file_bug674770-1.html" id="link2">test</a>
 </div>
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 SimpleTest.waitForExplicitFinish();
 SimpleTest.waitForFocus(function() {
-  SpecialPowers.pushPrefEnv({"set":[["middlemouse.paste", true], ["dom.ipc.processCount", 1]]}, startTest);
+  SpecialPowers.pushPrefEnv({"set":[["middlemouse.paste", true], ["dom.ipc.processCount", 1]]}, startTests);
 });
-function startTest() {
-  localStorage.removeItem("clicked");
-  window.linkWasClicked = false;
 
-  var link = document.querySelector("#link1");
-  addEventListener("storage", function(e) {
-    is(e.key, "clicked", "Correct event");
-    is(e.newValue, "true", "Correct value");
-    window.linkWasClicked = true;
-  }, false);
-  synthesizeMouseAtCenter(link, {button: 1});
+function startTests() {
+  var tests = [
+    { description: "Testing link in <div>: ",
+      target: function () { return document.querySelector("#link1"); },
+      linkShouldWork: true },
+    { description: "Testing link in <div contenteditable>: ",
+      target: function () { return document.querySelector("#link2"); },
+      linkShouldWork: false },
+  ];
+  var currentTest;
+  function runNextTest() {
+    localStorage.removeItem("clicked");
+    currentTest = tests.shift();
+    if (!currentTest) {
+      SimpleTest.finish();
+      return;
+    }
+    ok(true, currentTest.description + "Starting to test...");
+    synthesizeMouseAtCenter(currentTest.target(), { button: 1 });
+  }
 
-  hitEventLoop(function() {
-    ok(window.linkWasClicked, "The click operation worked successfully");
-    window.linkWasClicked = false;
 
-    link = document.querySelector("#link2");
-    localStorage.removeItem("clicked");
-    synthesizeMouseAtCenter(link, {button: 1});
-
-    hitEventLoop(function() {
-      ok(!window.linkWasClicked, "The click operation shouldn't work in the contenteditable area");
+  addEventListener("storage", function(e) {
+    is(e.key, "clicked", currentTest.description + "Key should always be 'clicked'");
+    is(e.newValue, "true", currentTest.description + "Value should always be 'true'");
+    ok(currentTest.linkShouldWork, currentTest.description + "The click operation on the link " + (currentTest.linkShouldWork ? "should work" : "shouldn't work"));
+    SimpleTest.executeSoon(runNextTest);
+  }, false);
 
-      localStorage.removeItem("clicked");
-      SimpleTest.finish();
-    }, 500);
-  }, 500);
-}
+  SpecialPowers.addSystemEventListener(window, "click", function (aEvent) {
+    // When the click event should cause default action, e.g., opening the link,
+    // the event shouldn't have been consumed except the link handler.
+    // However, in e10s mode, it's not consumed during propagating the event but
+    // in non-e10s mode, it's consumed during the propagation.  Therefore,
+    // we cannot check defaultPrevented value when the link should work as is
+    // if there is no way to detect if it's running in e10s mode or not.
+    // So, let's skip checking Event.defaultPrevented value when the link should
+    // work.  In such case, we should receive "storage" event later.
+    if (currentTest.linkShouldWork) {
+      return;
+    }
 
-function hitEventLoop(func, times) {
-  if (times > 0) {
-    setTimeout(hitEventLoop, 0, func, times - 1);
-  } else {
-    setTimeout(func, 0);
-  }
+    ok(SpecialPowers.defaultPreventedInAnyGroup(aEvent),
+       currentTest.description + "The default action should be consumed because the link should work as is");
+    if (SpecialPowers.defaultPreventedInAnyGroup(aEvent)) {
+      // In this case, "storage" event won't be fired.
+      SimpleTest.executeSoon(runNextTest);
+    }
+  }, false);
+
+  SimpleTest.executeSoon(runNextTest);
 }
 
 </script>
 </pre>
 </body>
 </html>
--- a/layout/base/nsFrameTraversal.cpp
+++ b/layout/base/nsFrameTraversal.cpp
@@ -114,25 +114,23 @@ protected:
   nsIFrame* GetLastChildInner(nsIFrame* aFrame) override;  
   
   nsIFrame* GetNextSiblingInner(nsIFrame* aFrame) override;
   nsIFrame* GetPrevSiblingInner(nsIFrame* aFrame) override;  
 };
 
 /************IMPLEMENTATIONS**************/
 
-nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult)
+nsresult
+NS_CreateFrameTraversal(nsIFrameTraversal** aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
-  *aResult = nullptr;
 
-  nsCOMPtr<nsIFrameTraversal> t(new nsFrameTraversal());
-
-  *aResult = t;
-  NS_ADDREF(*aResult);
+  nsCOMPtr<nsIFrameTraversal> t = new nsFrameTraversal();
+  t.forget(aResult);
 
   return NS_OK;
 }
 
 nsresult
 NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
                      nsPresContext* aPresContext,
                      nsIFrame *aStart,
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1537,23 +1537,24 @@ PresShell::GetDisplaySelection(int16_t *
 
 NS_IMETHODIMP
 PresShell::GetSelection(RawSelectionType aRawSelectionType,
                         nsISelection **aSelection)
 {
   if (!aSelection || !mSelection)
     return NS_ERROR_NULL_POINTER;
 
-  *aSelection = mSelection->GetSelection(ToSelectionType(aRawSelectionType));
-
-  if (!(*aSelection))
+  nsCOMPtr<nsISelection> selection =
+    mSelection->GetSelection(ToSelectionType(aRawSelectionType));
+
+  if (!selection) {
     return NS_ERROR_INVALID_ARG;
-
-  NS_ADDREF(*aSelection);
-
+  }
+
+  selection.forget(aSelection);
   return NS_OK;
 }
 
 Selection*
 PresShell::GetCurrentSelection(SelectionType aSelectionType)
 {
   if (!mSelection)
     return nullptr;
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1736,31 +1736,29 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
             continue;
 
           if (!tracingStyleFlush) {
             tracingStyleFlush = true;
             profiler_tracing("Paint", "Styles", mStyleCause, TRACING_INTERVAL_START);
             mStyleCause = nullptr;
           }
 
-          NS_ADDREF(shell);
+          nsCOMPtr<nsIPresShell> shellKungFuDeathGrip(shell);
           mStyleFlushObservers.RemoveElement(shell);
           RestyleManagerHandle restyleManager =
             shell->GetPresContext()->RestyleManager();
           restyleManager->SetObservingRefreshDriver(false);
           shell->FlushPendingNotifications(ChangesToFlush(Flush_Style, false));
           // Inform the FontFaceSet that we ticked, so that it can resolve its
           // ready promise if it needs to (though it might still be waiting on
           // a layout flush).
           nsPresContext* presContext = shell->GetPresContext();
           if (presContext) {
             presContext->NotifyFontFaceSetOnRefresh();
           }
-          NS_RELEASE(shell);
-
           mNeedToRecomputeVisibility = true;
         }
 
 
         if (tracingStyleFlush) {
           profiler_tracing("Paint", "Styles", TRACING_INTERVAL_END);
         }
       }
@@ -1778,32 +1776,30 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
           continue;
 
         if (!tracingLayoutFlush) {
           tracingLayoutFlush = true;
           profiler_tracing("Paint", "Reflow", mReflowCause, TRACING_INTERVAL_START);
           mReflowCause = nullptr;
         }
 
-        NS_ADDREF(shell);
+        nsCOMPtr<nsIPresShell> shellKungFuDeathGrip(shell);
         mLayoutFlushObservers.RemoveElement(shell);
         shell->mReflowScheduled = false;
         shell->mSuppressInterruptibleReflows = false;
         mozFlushType flushType = HasPendingAnimations(shell)
                                ? Flush_Layout
                                : Flush_InterruptibleLayout;
         shell->FlushPendingNotifications(ChangesToFlush(flushType, false));
         // Inform the FontFaceSet that we ticked, so that it can resolve its
         // ready promise if it needs to.
         nsPresContext* presContext = shell->GetPresContext();
         if (presContext) {
           presContext->NotifyFontFaceSetOnRefresh();
         }
-        NS_RELEASE(shell);
-
         mNeedToRecomputeVisibility = true;
       }
 
       if (tracingLayoutFlush) {
         profiler_tracing("Paint", "Reflow", TRACING_INTERVAL_END);
       }
     }
 
--- a/layout/build/nsContentDLF.cpp
+++ b/layout/build/nsContentDLF.cpp
@@ -324,18 +324,17 @@ nsContentDLF::CreateBlankDocument(nsILoa
     }
   }
 
   // add a nice bow
   if (NS_SUCCEEDED(rv)) {
     blankDoc->SetDocumentCharacterSetSource(kCharsetFromDocTypeDefault);
     blankDoc->SetDocumentCharacterSet(NS_LITERAL_CSTRING("UTF-8"));
     
-    *aDocument = blankDoc;
-    NS_ADDREF(*aDocument);
+    blankDoc.forget(aDocument);
   }
   return rv;
 }
 
 
 nsresult
 nsContentDLF::CreateDocument(const char* aCommand,
                              nsIChannel* aChannel,
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -1902,31 +1902,29 @@ BuildTextRunsScanner::GetNextBreakBefore
   *aIndex = index + 1;
   return static_cast<nsTextFrame*>(mLineBreakBeforeFrames.ElementAt(index));
 }
 
 static gfxFontGroup*
 GetFontGroupForFrame(nsIFrame* aFrame, float aFontSizeInflation,
                      nsFontMetrics** aOutFontMetrics = nullptr)
 {
-  if (aOutFontMetrics)
-    *aOutFontMetrics = nullptr;
-
   RefPtr<nsFontMetrics> metrics =
     nsLayoutUtils::GetFontMetricsForFrame(aFrame, aFontSizeInflation);
-
+  gfxFontGroup* fontGroup = metrics->GetThebesFontGroup();
+
+  // Populate outparam before we return:
   if (aOutFontMetrics) {
-    *aOutFontMetrics = metrics;
-    NS_ADDREF(*aOutFontMetrics);
+    metrics.forget(aOutFontMetrics);
   }
   // XXX this is a bit bogus, we're releasing 'metrics' so the
   // returned font-group might actually be torn down, although because
   // of the way the device context caches font metrics, this seems to
   // not actually happen. But we should fix this.
-  return metrics->GetThebesFontGroup();
+  return fontGroup;
 }
 
 static already_AddRefed<DrawTarget>
 CreateReferenceDrawTarget(nsTextFrame* aTextFrame)
 {
   RefPtr<gfxContext> ctx =
     aTextFrame->PresContext()->PresShell()->CreateReferenceRenderingContext();
   RefPtr<DrawTarget> dt = ctx->GetDrawTarget();
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -91,19 +91,17 @@ SERVO_BINDING_FUNC(Servo_Initialize, voi
 // Shut down Servo components. Should be called exactly once at shutdown.
 SERVO_BINDING_FUNC(Servo_Shutdown, void)
 
 // Restyle hints
 SERVO_BINDING_FUNC(Servo_ComputeRestyleHint, nsRestyleHint,
                    RawGeckoElement* element, ServoElementSnapshot* snapshot,
                    RawServoStyleSetBorrowed set)
 
-// Restyle the given document or subtree
-SERVO_BINDING_FUNC(Servo_RestyleDocument, void,
-                   RawGeckoDocumentBorrowed doc, RawServoStyleSetBorrowedMut set)
+// Restyle the given subtree.
 SERVO_BINDING_FUNC(Servo_RestyleSubtree, void,
                    RawGeckoNodeBorrowed node, RawServoStyleSetBorrowedMut set)
 
 // Style-struct management.
 #define STYLE_STRUCT(name, checkdata_cb)                            \
   struct nsStyle##name;                                             \
   SERVO_BINDING_FUNC(Servo_GetStyle##name, const nsStyle##name*,  \
                      ServoComputedValuesBorrowed computed_values)
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -2798,16 +2798,18 @@ css::ImageValue::ImageValue(nsIURI* aURI
 
   if (loadingDoc != aDocument) {
     aDocument->StyleImageLoader()->MaybeRegisterCSSImage(this);
   }
 }
 
 css::ImageValue::~ImageValue()
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
   for (auto iter = mRequests.Iter(); !iter.Done(); iter.Next()) {
     nsIDocument* doc = iter.Key();
     RefPtr<imgRequestProxy>& proxy = iter.Data();
 
     if (doc) {
       doc->StyleImageLoader()->DeregisterCSSImage(this);
     }
 
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2190,17 +2190,17 @@ nsStyleImage::ComputeActualCropRect(nsIn
     *aIsEntireImage = aActualCropRect.IsEqualInterior(imageRect);
   }
   return true;
 }
 
 nsresult
 nsStyleImage::StartDecoding() const
 {
-  if ((mType == eStyleImageType_Image) && mImage) {
+  if (mType == eStyleImageType_Image) {
     return mImage->StartDecoding();
   }
   return NS_OK;
 }
 
 bool
 nsStyleImage::IsOpaque() const
 {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -360,16 +360,17 @@ struct nsStyleImage
   void SetElementId(const char16_t* aElementId);
   void SetCropRect(mozilla::UniquePtr<nsStyleSides> aCropRect);
 
   nsStyleImageType GetType() const {
     return mType;
   }
   imgRequestProxy* GetImageData() const {
     MOZ_ASSERT(mType == eStyleImageType_Image, "Data is not an image!");
+    MOZ_ASSERT(mImage);
     MOZ_ASSERT(mImageTracked,
                "Should be tracking any image we're going to use!");
     return mImage;
   }
   nsStyleGradient* GetGradientData() const {
     NS_ASSERTION(mType == eStyleImageType_Gradient, "Data is not a gradient!");
     return mGradient;
   }
--- a/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc
@@ -24,18 +24,20 @@
 #include <sys/videodev2.h>
 #else
 #include <linux/videodev2.h>
 #endif
 
 #include "webrtc/system_wrappers/interface/ref_count.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 
+#ifdef WEBRTC_LINUX
 #define EVENT_SIZE  ( sizeof (struct inotify_event) )
 #define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )
+#endif
 
 namespace webrtc
 {
 namespace videocapturemodule
 {
 VideoCaptureModule::DeviceInfo*
 VideoCaptureImpl::CreateDeviceInfo(const int32_t id)
 {
@@ -44,16 +46,17 @@ VideoCaptureImpl::CreateDeviceInfo(const
     if (!deviceInfo)
     {
         deviceInfo = NULL;
     }
 
     return deviceInfo;
 }
 
+#ifdef WEBRTC_LINUX
 void DeviceInfoLinux::HandleEvent(inotify_event* event)
 {
     switch (event->mask) {
         case IN_CREATE:
             DeviceChange();
             break;
         case IN_DELETE:
             DeviceChange();
@@ -153,44 +156,51 @@ bool DeviceInfoLinux::InotifyProcess()
         }
 
         close(_fd);
         return true;
     } else {
         return false;
     }
 }
+#endif
 
 DeviceInfoLinux::DeviceInfoLinux(const int32_t id)
     : DeviceInfoImpl(id)
+#ifdef WEBRTC_LINUX
     , _isShutdown(0)
+#endif
 {
+#ifdef WEBRTC_LINUX
     _inotifyEventThread = ThreadWrapper::CreateThread(
         InotifyEventThread, this, "InotifyEventThread");
 
     if (_inotifyEventThread)
     {
         _inotifyEventThread->Start();
         _inotifyEventThread->SetPriority(kHighPriority);
     }
+#endif
 }
 
 int32_t DeviceInfoLinux::Init()
 {
     return 0;
 }
 
 DeviceInfoLinux::~DeviceInfoLinux()
 {
+#ifdef WEBRTC_LINUX
     ++_isShutdown;
 
     if (_inotifyEventThread) {
         _inotifyEventThread->Stop();
         _inotifyEventThread.reset();
     }
+#endif
 }
 
 uint32_t DeviceInfoLinux::NumberOfDevices()
 {
     WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideoCapture, _id, "%s", __FUNCTION__);
 
     uint32_t count = 0;
     char device[20];
@@ -389,87 +399,62 @@ bool DeviceInfoLinux::IsDeviceNameMatche
 {
     if (strncmp(deviceUniqueIdUTF8, name, strlen(name)) == 0)
             return true;
     return false;
 }
 
 int32_t DeviceInfoLinux::FillCapabilities(int fd)
 {
-
-    // set image format
-    struct v4l2_format video_fmt;
-    memset(&video_fmt, 0, sizeof(struct v4l2_format));
-
-    video_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    video_fmt.fmt.pix.sizeimage = 0;
-
-    int totalFmts = 3;
-    unsigned int videoFormats[] = {
-        V4L2_PIX_FMT_MJPEG,
-        V4L2_PIX_FMT_YUV420,
-        V4L2_PIX_FMT_YUYV };
+    struct v4l2_fmtdesc fmt;
+    struct v4l2_frmsizeenum frmsize;
+    struct v4l2_frmivalenum frmival;
 
-    int sizes = 13;
-    unsigned int size[][2] = { { 128, 96 }, { 160, 120 }, { 176, 144 },
-                               { 320, 240 }, { 352, 288 }, { 640, 480 },
-                               { 704, 576 }, { 800, 600 }, { 960, 720 },
-                               { 1280, 720 }, { 1024, 768 }, { 1440, 1080 },
-                               { 1920, 1080 } };
-
-    int index = 0;
-    for (int fmts = 0; fmts < totalFmts; fmts++)
-    {
-        for (int i = 0; i < sizes; i++)
-        {
-            video_fmt.fmt.pix.pixelformat = videoFormats[fmts];
-            video_fmt.fmt.pix.width = size[i][0];
-            video_fmt.fmt.pix.height = size[i][1];
+    fmt.index = 0;
+    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) >= 0) {
+        frmsize.pixel_format = fmt.pixelformat;
+        frmsize.index = 0;
+        while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0) {
+            if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
+                frmival.index = 0;
+                frmival.pixel_format = fmt.pixelformat;
+                frmival.width = frmsize.discrete.width;
+                frmival.height = frmsize.discrete.height;
+                if (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) >= 0) {
+                    if (fmt.pixelformat == V4L2_PIX_FMT_YUYV ||
+                        fmt.pixelformat == V4L2_PIX_FMT_YUV420 ||
+                        fmt.pixelformat == V4L2_PIX_FMT_MJPEG) {
 
-            if (ioctl(fd, VIDIOC_TRY_FMT, &video_fmt) >= 0)
-            {
-                if ((video_fmt.fmt.pix.width == size[i][0])
-                    && (video_fmt.fmt.pix.height == size[i][1]))
-                {
-                    VideoCaptureCapability cap;
-                    cap.width = video_fmt.fmt.pix.width;
-                    cap.height = video_fmt.fmt.pix.height;
-                    cap.expectedCaptureDelay = 120;
-                    if (videoFormats[fmts] == V4L2_PIX_FMT_YUYV)
-                    {
-                        cap.rawType = kVideoYUY2;
-                    }
-                    else if (videoFormats[fmts] == V4L2_PIX_FMT_YUV420)
-                    {
-                        cap.rawType = kVideoI420;
+                        VideoCaptureCapability cap;
+                        cap.width = frmsize.discrete.width;
+                        cap.height = frmsize.discrete.height;
+                        cap.expectedCaptureDelay = 120;
+
+                        if (fmt.pixelformat == V4L2_PIX_FMT_YUYV)
+                        {
+                            cap.rawType = kVideoYUY2;
+                        }
+                        else if (fmt.pixelformat == V4L2_PIX_FMT_YUV420)
+                        {
+                            cap.rawType = kVideoI420;
+                        }
+                        else if (fmt.pixelformat == V4L2_PIX_FMT_MJPEG)
+                        {
+                            cap.rawType = kVideoMJPEG;
+                        }
+
+                        cap.maxFPS = frmival.discrete.denominator / frmival.discrete.numerator;
+                        _captureCapabilities.push_back(cap);
                     }
-                    else if (videoFormats[fmts] == V4L2_PIX_FMT_MJPEG)
-                    {
-                        cap.rawType = kVideoMJPEG;
-                    }
-
-                    // get fps of current camera mode
-                    // V4l2 does not have a stable method of knowing so we just guess.
-                    if(cap.width >= 800 && cap.rawType != kVideoMJPEG)
-                    {
-                        cap.maxFPS = 15;
-                    }
-                    else
-                    {
-                        cap.maxFPS = 30;
-                    }
-
-                    _captureCapabilities.push_back(cap);
-                    index++;
-                    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
-                               "Camera capability, width:%d height:%d type:%d fps:%d",
-                               cap.width, cap.height, cap.rawType, cap.maxFPS);
                 }
             }
+            frmsize.index++;
         }
+        fmt.index++;
     }
 
     WEBRTC_TRACE(webrtc::kTraceInfo,
                  webrtc::kTraceVideoCapture,
                  _id,
                  "CreateCapabilityMap %u",
                  static_cast<unsigned int>(_captureCapabilities.size()));
     return _captureCapabilities.size();
--- a/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.h
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.h
@@ -8,19 +8,21 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
 #ifndef WEBRTC_MODULES_VIDEO_CAPTURE_MAIN_SOURCE_LINUX_DEVICE_INFO_LINUX_H_
 #define WEBRTC_MODULES_VIDEO_CAPTURE_MAIN_SOURCE_LINUX_DEVICE_INFO_LINUX_H_
 
 #include "webrtc/modules/video_capture/device_info_impl.h"
 #include "webrtc/modules/video_capture/video_capture_impl.h"
+#ifdef WEBRTC_LINUX
 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
 #include "webrtc/system_wrappers/interface/atomic32.h"
 #include <sys/inotify.h>
+#endif
 
 namespace webrtc
 {
 namespace videocapturemodule
 {
 class DeviceInfoLinux: public DeviceInfoImpl
 {
 public:
@@ -46,21 +48,23 @@ public:
         uint32_t /*positionX*/,
         uint32_t /*positionY*/) { return -1;}
     int32_t FillCapabilities(int fd);
     int32_t Init();
 private:
 
     bool IsDeviceNameMatches(const char* name, const char* deviceUniqueIdUTF8);
 
+#ifdef WEBRTC_LINUX
     void HandleEvent(inotify_event* event);
     int EventCheck();
     int HandleEvents();
     int ProcessInotifyEvents();
     rtc::scoped_ptr<ThreadWrapper> _inotifyEventThread;
     static bool InotifyEventThread(void*);
     bool InotifyProcess();
     int _fd, _wd_v4l, _wd_snd; /* accessed on InotifyEventThread thread */
     Atomic32 _isShutdown;
+#endif
 };
 }  // namespace videocapturemodule
 }  // namespace webrtc
 #endif // WEBRTC_MODULES_VIDEO_CAPTURE_MAIN_SOURCE_LINUX_DEVICE_INFO_LINUX_H_
--- a/mobile/android/base/java/org/mozilla/gecko/DynamicToolbar.java
+++ b/mobile/android/base/java/org/mozilla/gecko/DynamicToolbar.java
@@ -55,19 +55,27 @@ public class DynamicToolbar {
     }
 
     public static boolean isForceDisabled() {
         // Force-disable dynamic toolbar on the variants of the Galaxy Note 10.1
         // and Note 8.0 running Android 4.1.2. (Bug 1231554). This includes
         // the following model numbers:
         //  GT-N8000, GT-N8005, GT-N8010, GT-N8013, GT-N8020
         //  GT-N5100, GT-N5110, GT-N5120
-        return Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN
+        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN
             && (Build.MODEL.startsWith("GT-N80") ||
-                Build.MODEL.startsWith("GT-N51"));
+                Build.MODEL.startsWith("GT-N51"))) {
+            return true;
+        }
+        // Also disable variants of the Galaxy Note 4 on Android 5.0.1 (Bug 1301593)
+        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
+            && (Build.MODEL.startsWith("SM-910"))) {
+            return true;
+        }
+        return false;
     }
 
     public void destroy() {
         PrefsHelper.removeObserver(prefObserver);
     }
 
     public void setLayerView(LayerView layerView) {
         ThreadUtils.assertOnUiThread();
--- a/mobile/android/base/java/org/mozilla/gecko/media/Codec.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/Codec.java
@@ -47,17 +47,17 @@ import java.util.Queue;
         @Override
         public void onOutputBufferAvailable(AsyncCodec codec, int index, MediaCodec.BufferInfo info) {
             if (mFlushing) {
                 // Flush invalidates all buffers.
                 return;
             }
             ByteBuffer buffer = codec.getOutputBuffer(index);
             try {
-                mRemote.onOutput(new Sample(buffer, info));
+                mRemote.onOutput(new Sample(buffer, info, null));
             } catch (TransactionTooLargeException ttle) {
                 Log.e(LOGTAG, "Output is too large:" + ttle.getMessage());
                 outputDummy(info);
             } catch (RemoteException e) {
                 // Dead recipient.
                 e.printStackTrace();
             }
             mCodec.releaseOutputBuffer(index, true);
--- a/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java
@@ -9,16 +9,17 @@ import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.mozglue.JNIObject;
 
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.media.MediaCodec;
 import android.media.MediaCodec.BufferInfo;
+import android.media.MediaCodec.CryptoInfo;
 import android.media.MediaFormat;
 import android.os.DeadObjectException;
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.Surface;
 
 import java.nio.ByteBuffer;
 // Proxy class of ICodec binder.
@@ -126,23 +127,23 @@ public final class CodecProxy {
             return true;
         } catch (RemoteException e) {
             e.printStackTrace();
             return false;
         }
     }
 
     @WrapForJNI
-    public synchronized boolean input(byte[] bytes, BufferInfo info) {
+    public synchronized boolean input(byte[] bytes, BufferInfo info, CryptoInfo cryptoInfo) {
         if (mRemote == null) {
             Log.e(LOGTAG, "cannot send input to an ended codec");
             return false;
         }
         Sample sample = (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) ?
-                        Sample.EOS : new Sample(ByteBuffer.wrap(bytes), info);
+                        Sample.EOS : new Sample(ByteBuffer.wrap(bytes), info, cryptoInfo);
         try {
             mRemote.queueInput(sample);
         } catch (DeadObjectException e) {
             return false;
         } catch (RemoteException e) {
             e.printStackTrace();
             Log.e(LOGTAG, "fail to input sample:" + sample);
             return false;
--- a/mobile/android/base/java/org/mozilla/gecko/media/Sample.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/Sample.java
@@ -1,46 +1,49 @@
 /* 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/. */
 
 package org.mozilla.gecko.media;
 
 import android.media.MediaCodec;
 import android.media.MediaCodec.BufferInfo;
+import android.media.MediaCodec.CryptoInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import java.nio.ByteBuffer;
 
 // POD carrying input sample data and info cross process.
 public final class Sample implements Parcelable {
     public static final Sample EOS;
     static {
         BufferInfo eosInfo = new BufferInfo();
         eosInfo.set(0, 0, Long.MIN_VALUE, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
-        EOS = new Sample(null, eosInfo);
+        EOS = new Sample(null, eosInfo, null);
     }
 
     public BufferInfo info;
     public ByteBuffer bytes;
+    public CryptoInfo cryptoInfo;
 
-    public Sample(ByteBuffer bytes, BufferInfo info) {
+    public Sample(ByteBuffer bytes, BufferInfo info, CryptoInfo cryptoInfo) {
         this.info = info;
         this.bytes = bytes;
+        this.cryptoInfo = cryptoInfo;
     }
 
     protected Sample(Parcel in) {
         readFromParcel(in);
     }
 
     public static Sample createDummyWithInfo(BufferInfo info) {
         BufferInfo dummyInfo = new BufferInfo();
         dummyInfo.set(0, 0, info.presentationTimeUs, info.flags);
-        return new Sample(null, dummyInfo);
+        return new Sample(null, dummyInfo, null);
     }
 
     public boolean isDummy() {
         return !isEOS() && bytes == null && info.size == 0;
     }
 
     public boolean isEOS() {
         return (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
@@ -69,23 +72,53 @@ public final class Sample implements Par
         int size = 0;
         byte[] buf = in.createByteArray();
         if (buf != null) {
             bytes = ByteBuffer.wrap(buf);
             size = buf.length;
         }
         info = new BufferInfo();
         info.set(0, size, pts, flags);
+
+        int hasCryptoInfo = in.readInt();
+        if (hasCryptoInfo == 1) {
+            byte[] iv = in.createByteArray();
+            byte[] key = in.createByteArray();
+            int mode = in.readInt();
+            int[] numBytesOfClearData = in.createIntArray();
+            int[] numBytesOfEncryptedData = in.createIntArray();
+            int numSubSamples = in.readInt();
+            cryptoInfo = new CryptoInfo();
+            cryptoInfo.set(numSubSamples,
+                           numBytesOfClearData,
+                           numBytesOfEncryptedData,
+                           key,
+                           iv,
+                           mode);
+        } else {
+            cryptoInfo = null;
+        }
     }
 
     @Override
     public void writeToParcel(Parcel dest, int parcelableFlags) {
         dest.writeLong(info.presentationTimeUs);
         dest.writeInt(info.flags);
         dest.writeByteArray(byteArrayFromBuffer(bytes, info.offset, info.size));
+        if (cryptoInfo != null) {
+            dest.writeInt(1);
+            dest.writeByteArray(cryptoInfo.iv);
+            dest.writeByteArray(cryptoInfo.key);
+            dest.writeInt(cryptoInfo.mode);
+            dest.writeIntArray(cryptoInfo.numBytesOfClearData);
+            dest.writeIntArray(cryptoInfo.numBytesOfEncryptedData);
+            dest.writeInt(cryptoInfo.numSubSamples);
+        } else {
+            dest.writeInt(0);
+        }
     }
 
     public static byte[] byteArrayFromBuffer(ByteBuffer buffer, int offset, int size) {
         if (buffer == null || buffer.capacity() == 0 || size == 0) {
             return null;
         }
         if (buffer.hasArray() && offset == 0 && buffer.array().length == size) {
             return buffer.array();
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -384,20 +384,16 @@ var BrowserApp = {
     Services.obs.addObserver(this, "gather-telemetry", false);
     Services.obs.addObserver(this, "keyword-search", false);
     Services.obs.addObserver(this, "sessionstore-state-purge-complete", false);
     Services.obs.addObserver(this, "Fonts:Reload", false);
     Services.obs.addObserver(this, "Vibration:Request", false);
 
     Messaging.addListener(this.getHistory.bind(this), "Session:GetHistory");
 
-    function showFullScreenWarning() {
-      Snackbars.show(Strings.browser.GetStringFromName("alertFullScreenToast"), Snackbars.LENGTH_LONG);
-    }
-
     window.addEventListener("fullscreen", function() {
       Messaging.sendRequest({
         type: window.fullScreen ? "ToggleChrome:Hide" : "ToggleChrome:Show"
       });
     }, false);
 
     window.addEventListener("fullscreenchange", (e) => {
       // This event gets fired on the document and its entire ancestor chain
@@ -406,30 +402,24 @@ var BrowserApp = {
       // (per spec). This means the last event on enabling will be for the innermost
       // document, which will have fullscreenElement set correctly.
       let doc = e.target;
       Messaging.sendRequest({
         type: doc.fullscreenElement ? "DOMFullScreen:Start" : "DOMFullScreen:Stop",
         rootElement: doc.fullscreenElement == doc.documentElement
       });
 
-      if (doc.fullscreenElement) {
-        showFullScreenWarning();
-      } else if (this.fullscreenTransitionTab) {
+      if (this.fullscreenTransitionTab) {
         // Tab selection has changed during a fullscreen transition, handle it now.
         let tab = this.fullscreenTransitionTab;
         this.fullscreenTransitionTab = null;
         this._handleTabSelected(tab);
       }
     }, false);
 
-    // When a restricted key is pressed in DOM full-screen mode, we should display
-    // the "Press ESC to exit" warning message.
-    window.addEventListener("MozShowFullScreenWarning", showFullScreenWarning, true);
-
     NativeWindow.init();
     FormAssistant.init();
     IndexedDB.init();
     XPInstallObserver.init();
     CharacterEncoding.init();
     ActivityObserver.init();
     RemoteDebugger.init();
     UserAgentOverrides.init();
--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -566,17 +566,17 @@ SessionStore.prototype = {
     this._updateCrashReportURL(aWindow);
   },
 
   onTabRemove: function ss_onTabRemove(aWindow, aBrowser, aNoNotification) {
     // Cleanup event listeners
     aBrowser.removeEventListener("DOMTitleChanged", this, true);
     aBrowser.removeEventListener("load", this, true);
     aBrowser.removeEventListener("pageshow", this, true);
-    aBrowser.removeListener("AboutReaderContentReady", this, true);
+    aBrowser.removeEventListener("AboutReaderContentReady", this, true);
     aBrowser.removeEventListener("change", this, true);
     aBrowser.removeEventListener("input", this, true);
     aBrowser.removeEventListener("DOMAutoComplete", this, true);
     aBrowser.removeEventListener("scroll", this, true);
     aBrowser.removeEventListener("resize", this, true);
 
     delete aBrowser.__SS_data;
 
--- a/mobile/android/locales/en-US/chrome/browser.properties
+++ b/mobile/android/locales/en-US/chrome/browser.properties
@@ -27,18 +27,16 @@ alertDownloadsResume=Resume
 alertDownloadsCancel=Cancel
 # LOCALIZATION NOTE (alertDownloadSucceeded): This text is shown as a snackbar inside the app after a
 # successful download. %S will be replaced by the file name of the download.
 alertDownloadSucceeded=%S downloaded
 # LOCALIZATION NOTE (downloads.disabledInGuest): This message appears in a toast
 # when the user tries to download something in Guest mode.
 downloads.disabledInGuest=Downloads are disabled in guest sessions
 
-alertFullScreenToast=Press BACK to leave full-screen mode
-
 # LOCALIZATION NOTE (alertSearchEngineAddedToast, alertSearchEngineErrorToast, alertSearchEngineDuplicateToast)
 # %S will be replaced by the name of the search engine (exposed by the current page)
 # that has been added; for example, 'Google'.
 alertSearchEngineAddedToast='%S' has been added as a search engine
 alertSearchEngineErrorToast=Couldn't add '%S' as a search engine
 alertSearchEngineDuplicateToast='%S' is already one of your search engines
 
 alertPrintjobToast=Printing…
--- a/python/mozbuild/mozbuild/action/test_archive.py
+++ b/python/mozbuild/mozbuild/action/test_archive.py
@@ -92,16 +92,45 @@ ARCHIVE_FILES = {
             ],
         },
         {
             'source': buildconfig.topobjdir,
             'base': '_tests',
             'pattern': 'modules/**',
         },
         {
+            'source': buildconfig.topsrcdir,
+            'base': 'testing/marionette',
+            'patterns': [
+                'client/**',
+                'mach_test_package_commands.py',
+            ],
+            'dest': 'marionette',
+        },
+        {
+            'source': buildconfig.topsrcdir,
+            'base': 'testing/marionette/harness',
+            'pattern': '**',
+            'dest': 'marionette',
+            'ignore': [
+                'marionette/tests'
+            ]
+        },
+        {
+            'source': buildconfig.topsrcdir,
+            'base': '',
+            'manifests': [
+                'testing/marionette/harness/marionette/tests/unit-tests.ini',
+                'testing/marionette/harness/marionette/tests/webapi-tests.ini',
+            ],
+            # We also need the manifests and harness_unit tests
+            'pattern': 'testing/marionette/harness/marionette/tests/**',
+            'dest': 'marionette/tests',
+        },
+        {
             'source': buildconfig.topobjdir,
             'base': '_tests',
             'pattern': 'mozbase/**',
         },
         {
             'source': buildconfig.topsrcdir,
             'base': 'testing',
             'pattern': 'firefox-ui/**',
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -1526,20 +1526,16 @@ VARIABLES = {
     'PUPPETEER_FIREFOX_MANIFESTS': (ManifestparserManifestList, list,
         """List of manifest files defining puppeteer unit tests for Firefox.
         """),
 
     'MARIONETTE_LAYOUT_MANIFESTS': (ManifestparserManifestList, list,
         """List of manifest files defining marionette-layout tests.
         """),
 
-    'MARIONETTE_LOOP_MANIFESTS': (ManifestparserManifestList, list,
-        """List of manifest files defining marionette-loop tests.
-        """),
-
     'MARIONETTE_UNIT_MANIFESTS': (ManifestparserManifestList, list,
         """List of manifest files defining marionette-unit tests.
         """),
 
     'MARIONETTE_UPDATE_MANIFESTS': (ManifestparserManifestList, list,
         """List of manifest files defining marionette-update tests.
         """),
 
--- a/python/mozbuild/mozbuild/testing.py
+++ b/python/mozbuild/mozbuild/testing.py
@@ -279,17 +279,16 @@ TEST_MANIFESTS = dict(
     JETPACK_ADDON=('jetpack-addon', 'testing/mochitest', 'jetpack-addon', False),
     FIREFOX_UI_FUNCTIONAL=('firefox-ui-functional', 'firefox-ui', '.', False),
     FIREFOX_UI_UPDATE=('firefox-ui-update', 'firefox-ui', '.', False),
     PUPPETEER_FIREFOX=('firefox-ui-functional', 'firefox-ui', '.', False),
 
     # marionette tests are run from the srcdir
     # TODO(ato): make packaging work as for other test suites
     MARIONETTE=('marionette', 'marionette', '.', False),
-    MARIONETTE_LOOP=('marionette', 'marionette', '.', False),
     MARIONETTE_UNIT=('marionette', 'marionette', '.', False),
     MARIONETTE_UPDATE=('marionette', 'marionette', '.', False),
     MARIONETTE_WEBAPI=('marionette', 'marionette', '.', False),
 
     METRO_CHROME=('metro-chrome', 'testing/mochitest', 'metro', True),
     MOCHITEST=('mochitest', 'testing/mochitest', 'tests', True),
     MOCHITEST_CHROME=('chrome', 'testing/mochitest', 'chrome', True),
     WEBRTC_SIGNALLING_TEST=('steeplechase', 'steeplechase', '.', True),
--- a/security/sandbox/mac/Sandbox.mm
+++ b/security/sandbox/mac/Sandbox.mm
@@ -295,25 +295,22 @@ static const char contentSandboxRules[] 
   "      (global-name \"com.apple.windowserver.active\")\n"
   "      (global-name \"com.apple.audio.coreaudiod\")\n"
   "      (global-name \"com.apple.audio.audiohald\")\n"
   "      (global-name \"com.apple.PowerManagement.control\")\n"
   "      (global-name \"com.apple.cmio.VDCAssistant\")\n"
   "      (global-name \"com.apple.SystemConfiguration.configd\")\n"
   "      (global-name \"com.apple.iconservices\")\n"
   "      (global-name \"com.apple.cookied\")\n"
-  "      (global-name \"com.apple.printuitool.agent\")\n"
-  "      (global-name \"com.apple.printtool.agent\")\n"
   "      (global-name \"com.apple.cache_delete\")\n"
   "      (global-name \"com.apple.pluginkit.pkd\")\n"
   "      (global-name \"com.apple.bird\")\n"
   "      (global-name \"com.apple.ocspd\")\n"
   "      (global-name \"com.apple.cmio.AppleCameraAssistant\")\n"
-  "      (global-name \"com.apple.DesktopServicesHelper\")\n"
-  "      (global-name \"com.apple.printtool.daemon\"))\n"
+  "      (global-name \"com.apple.DesktopServicesHelper\"))\n"
   "\n"
   "  (allow iokit-open\n"
   "      (iokit-user-client-class \"IOHIDParamUserClient\")\n"
   "      (iokit-user-client-class \"IOAudioControlUserClient\")\n"
   "      (iokit-user-client-class \"IOAudioEngineUserClient\")\n"
   "      (iokit-user-client-class \"IGAccelDevice\")\n"
   "      (iokit-user-client-class \"nvDevice\")\n"
   "      (iokit-user-client-class \"nvSharedUserClient\")\n"
@@ -334,30 +331,27 @@ static const char contentSandboxRules[] 
   "  (allow-shared-preferences-read \"com.apple.ATS\")\n"
   "  (allow file-read-data (literal \"/Library/Preferences/.GlobalPreferences.plist\"))\n"
   "\n"
   "  (allow file-read*\n"
   "      (subpath \"/Library/Fonts\")\n"
   "      (subpath \"/Library/Audio/Plug-Ins\")\n"
   "      (subpath \"/Library/CoreMediaIO/Plug-Ins/DAL\")\n"
   "      (subpath \"/Library/Spelling\")\n"
-  "      (subpath \"/private/etc/cups/ppd\")\n"
-  "      (subpath \"/private/var/run/cupsd\")\n"
   "      (literal \"/\")\n"
   "      (literal \"/private/tmp\")\n"
   "      (literal \"/private/var/tmp\")\n"
   "\n"
   "      (home-literal \"/.CFUserTextEncoding\")\n"
   "      (home-literal \"/Library/Preferences/com.apple.DownloadAssessment.plist\")\n"
   "      (home-subpath \"/Library/Colors\")\n"
   "      (home-subpath \"/Library/Fonts\")\n"
   "      (home-subpath \"/Library/FontCollections\")\n"
   "      (home-subpath \"/Library/Keyboard Layouts\")\n"
   "      (home-subpath \"/Library/Input Methods\")\n"
-  "      (home-subpath \"/Library/PDF Services\")\n"
   "      (home-subpath \"/Library/Spelling\")\n"
   "\n"
   "      (subpath appdir-path)\n"
   "\n"
   "      (literal appPath)\n"
   "      (literal appBinaryPath))\n"
   "\n"
   "  (allow-shared-list \"org.mozilla.plugincontainer\")\n"
@@ -395,67 +389,16 @@ static const char contentSandboxRules[] 
   "      (allow file*\n"
   "          (require-not (home-subpath \"/Library\"))))\n"
   "    (allow file*\n"
   "        (require-all\n"
   "            (subpath home-path)\n"
   "            (require-not\n"
   "                (home-subpath \"/Library\")))))\n"
   "\n"
-  "; printing\n"
-  "  (allow authorization-right-obtain\n"
-  "         (right-name \"system.print.operator\")\n"
-  "         (right-name \"system.printingmanager\"))\n"
-  "  (allow mach-lookup\n"
-  "         (global-name \"com.apple.printuitool.agent\")\n"
-  "         (global-name \"com.apple.printtool.agent\")\n"
-  "         (global-name \"com.apple.printtool.daemon\")\n"
-  "         (global-name \"com.apple.sharingd\")\n"
-  "         (global-name \"com.apple.metadata.mds\")\n"
-  "         (global-name \"com.apple.mtmd.xpc\")\n"
-  "         (global-name \"com.apple.FSEvents\")\n"
-  "         (global-name \"com.apple.locum\")\n"
-  "         (global-name \"com.apple.ImageCaptureExtension2.presence\"))\n"
-  "  (allow file-read*\n"
-  "         (home-literal \"/.cups/lpoptions\")\n"
-  "         (home-literal \"/.cups/client.conf\")\n"
-  "         (literal \"/private/etc/cups/lpoptions\")\n"
-  "         (literal \"/private/etc/cups/client.conf\")\n"
-  "         (subpath \"/private/etc/cups/ppd\")\n"
-  "         (literal \"/private/var/run/cupsd\"))\n"
-  "  (allow-shared-preferences-read \"org.cups.PrintingPrefs\")\n"
-  "  (allow-shared-preferences-read \"com.apple.finder\")\n"
-  "  (allow-shared-preferences-read \"com.apple.LaunchServices\")\n"
-  "  (allow-shared-preferences-read \".GlobalPreferences\")\n"
-  "  (allow network-outbound\n"
-  "      (literal \"/private/var/run/cupsd\")\n"
-  "      (literal \"/private/var/run/mDNSResponder\"))\n"
-  "\n"
-  "; print preview\n"
-  "  (if (> macosMinorVersion 9)\n"
-  "      (allow lsopen))\n"
-  "  (allow file-write* file-issue-extension (var-folders2-regex \"/\"))\n"
-  "  (allow file-read-xattr (literal \"/Applications/Preview.app\"))\n"
-  "  (allow mach-task-name)\n"
-  "  (allow mach-register)\n"
-  "  (allow file-read-data\n"
-  "      (regex \"^/Library/Printers/[^/]+/PDEs/[^/]+.plugin\")\n"
-  "      (subpath \"/Library/PDF Services\")\n"
-  "      (subpath \"/Applications/Preview.app\")\n"
-  "      (home-literal \"/Library/Preferences/com.apple.ServicesMenu.Services.plist\"))\n"
-  "  (allow mach-lookup\n"
-  "      (global-name \"com.apple.pbs.fetch_services\")\n"
-  "      (global-name \"com.apple.tsm.uiserver\")\n"
-  "      (global-name \"com.apple.ls.boxd\")\n"
-  "      (global-name \"com.apple.coreservices.quarantine-resolver\")\n"
-  "      (global-name-regex \"_OpenStep$\"))\n"
-  "  (allow appleevent-send\n"
-  "      (appleevent-destination \"com.apple.preview\")\n"
-  "      (appleevent-destination \"com.apple.imagecaptureextension2\"))\n"
-  "\n"
   "; accelerated graphics\n"
   "  (allow-shared-preferences-read \"com.apple.opengl\")\n"
   "  (allow-shared-preferences-read \"com.nvidia.OpenGL\")\n"
   "  (allow mach-lookup\n"
   "      (global-name \"com.apple.cvmsServ\"))\n"
   "  (allow iokit-open\n"
   "      (iokit-connection \"IOAccelerator\")\n"
   "      (iokit-user-client-class \"IOAccelerationUserClient\")\n"
--- a/services/sync/modules/bookmark_validator.js
+++ b/services/sync/modules/bookmark_validator.js
@@ -36,18 +36,16 @@ this.EXPORTED_SYMBOLS = ["BookmarkValida
  * - deletedParents (array of ids) : List of records that aren't deleted but
  *   had deleted parents
  * - childrenOnNonFolder (array of ids): list of non-folders that still have
  *   children arrays
  * - duplicateChildren (array of ids): list of records who have the same
  *   child listed multiple times in their children array
  * - parentNotFolder (array of ids): list of records that have parents that
  *   aren't folders
- * - wrongParentName (array of ids): list of records whose parentName does
- *   not match the parent's actual title
  * - rootOnServer (boolean): true if the root came from the server
  *
  * - clientMissing: Array of ids on the server missing from the client
  * - serverMissing: Array of ids on the client missing from the server
  * - serverDeleted: Array of ids on the client that the server had marked as deleted.
  * - serverUnexpected: Array of ids that appear on the server but shouldn't
  *   because the client attempts to never upload them.
  * - differences: Array of {id: string, differences: string array} recording
@@ -67,17 +65,16 @@ class BookmarkProblemData {
     this.orphans = [];
     this.missingChildren = [];
     this.deletedChildren = [];
     this.multipleParents = [];
     this.deletedParents = [];
     this.childrenOnNonFolder = [];
     this.duplicateChildren = [];
     this.parentNotFolder = [];
-    this.wrongParentName = [];
 
     this.clientMissing = [];
     this.serverMissing = [];
     this.serverDeleted = [];
     this.serverUnexpected = [];
     this.differences = [];
     this.structuralDifferences = [];
   }
@@ -129,17 +126,16 @@ class BookmarkProblemData {
       { name: "orphans", count: this.orphans.length },
       { name: "missingChildren", count: this.missingChildren.length },
       { name: "deletedChildren", count: this.deletedChildren.length },
       { name: "multipleParents", count: this.multipleParents.length },
       { name: "deletedParents", count: this.deletedParents.length },
       { name: "childrenOnNonFolder", count: this.childrenOnNonFolder.length },
       { name: "duplicateChildren", count: this.duplicateChildren.length },
       { name: "parentNotFolder", count: this.parentNotFolder.length },
-      { name: "wrongParentName", count: this.wrongParentName.length },
     ];
     if (full) {
       let structural = this._summarizeDifferences("sdiff", this.structuralDifferences);
       result.push.apply(result, structural);
     }
     return result;
   }
 }
@@ -253,17 +249,16 @@ class BookmarkValidator {
         treeNode.childGUIDs = [];
         if (!treeNode.children) {
           treeNode.children = [];
         }
         for (let child of treeNode.children) {
           traverse(child);
           child.parent = treeNode;
           child.parentid = guid;
-          child.parentName = treeNode.title;
           treeNode.childGUIDs.push(child.guid);
         }
       }
     }
     traverse(clientTree);
     clientTree.id = 'places';
     this._followQueries(recordsByGuid);
     return records;
@@ -436,19 +431,20 @@ class BookmarkValidator {
       } else {
         parent.children.push(record);
       }
 
       if (parent.isDeleted && !record.isDeleted) {
         problemData.deletedParents.push(record.id);
       }
 
-      if (record.parentName !== parent.title && parent.id !== 'unfiled') {
-        problemData.wrongParentName.push(record.id);
-      }
+      // We used to check if the parentName on the server matches the actual
+      // local parent name, but given this is used only for de-duping a record
+      // the first time it is seen and expensive to keep up-to-date, we decided
+      // to just stop recording it. See bug 1276969 for more.
     }
 
     // Check that we aren't missing any children.
     for (let folder of folders) {
       folder.unfilteredChildren = folder.children;
       folder.children = [];
       for (let ci = 0; ci < folder.unfilteredChildren.length; ++ci) {
         let child = folder.unfilteredChildren[ci];
@@ -646,22 +642,16 @@ class BookmarkValidator {
       if ((client.title || "") !== (server.title || "")) {
         differences.push('title');
       }
 
       if (client.parentid || server.parentid) {
         if (client.parentid !== server.parentid) {
           structuralDifferences.push('parentid');
         }
-        // Need to special case 'unfiled' due to it's recent name change
-        // ("Other Bookmarks" vs "Unsorted Bookmarks"), otherwise this has a lot
-        // of false positives.
-        if (client.parentName !== server.parentName && server.parentid !== 'unfiled') {
-          differences.push('parentName');
-        }
       }
 
       if (client.tags || server.tags) {
         let cl = client.tags || [];
         let sl = server.tags || [];
         if (cl.length !== sl.length || !cl.every((tag, i) => sl.indexOf(tag) >= 0)) {
           differences.push('tags');
         }
--- a/services/sync/modules/engines.js
+++ b/services/sync/modules/engines.js
@@ -102,17 +102,17 @@ Tracker.prototype = {
       Utils.jsonSave("changes/" + this.file, this, this.changedIDs, cb);
     }, 1000, this, "_lazySave");
   },
 
   loadChangedIDs: function (cb) {
     Utils.jsonLoad("changes/" + this.file, this, function(json) {
       if (json && (typeof(json) == "object")) {
         this.changedIDs = json;
-      } else {
+      } else if (json !== null) {
         this._log.warn("Changed IDs file " + this.file + " contains non-object value.");
         json = null;
       }
       if (cb) {
         cb.call(this, json);
       }
     });
   },
--- a/services/sync/modules/util.js
+++ b/services/sync/modules/util.js
@@ -90,17 +90,17 @@ this.Utils = {
    */
   catch: function Utils_catch(func, exceptionCallback) {
     let thisArg = this;
     return function WrappedCatch() {
       try {
         return func.call(thisArg);
       }
       catch(ex) {
-        thisArg._log.debug("Exception", ex);
+        thisArg._log.debug("Exception calling " + (func.name || "anonymous function"), ex);
         if (exceptionCallback) {
           return exceptionCallback.call(thisArg, ex);
         }
         return null;
       }
     };
   },
 
@@ -353,17 +353,18 @@ this.Utils = {
     }
 
     let json;
 
     try {
       json = yield CommonUtils.readJSON(path);
     } catch (e) {
       if (e instanceof OS.File.Error && e.becauseNoSuchFile) {
-        // Ignore non-existent files.
+        // Ignore non-existent files, but explicitly return null.
+        json = null;
       } else {
         if (that._log) {
           that._log.debug("Failed to load json", e);
         }
       }
     }
 
     callback.call(that, json);
--- a/services/sync/tests/tps/all_tests.json
+++ b/services/sync/tests/tps/all_tests.json
@@ -11,17 +11,16 @@
     "test_bug556509.js",
     "test_bug562515.js",
     "test_bug563989.js",
     "test_bug535326.js",
     "test_bug501528.js",
     "test_bug575423.js",
     "test_bug546807.js",
     "test_history_collision.js",
-    "test_privbrw_formdata.js",
     "test_privbrw_passwords.js",
     "test_privbrw_tabs.js",
     "test_bookmarks_in_same_named_folder.js",
     "test_client_wipe.js",
     "test_special_tabs.js",
     "test_addon_sanity.js",
     "test_addon_restartless_xpi.js",
     "test_addon_nonrestartless_xpi.js",
--- a/services/sync/tests/tps/test_formdata.js
+++ b/services/sync/tests/tps/test_formdata.js
@@ -26,32 +26,42 @@ var formdata1 = [
     value: "failure",
     date: -2
   },
   { fieldname: "username",
     value: "joe"
   }
 ];
 
+// This is currently pointless - it *looks* like it is trying to check that
+// one of the entries in formdata1 has been removed, but (a) the delete code
+// isn't active (see comments below), and (b) the way the verification works
+// means it would never do the right thing - it only checks all the entries
+// here exist, but not that they are the only entries in the DB.
 var formdata2 = [
   { fieldname: "testing",
     value: "success",
     date: -1
   },
   { fieldname: "username",
     value: "joe"
   }
 ];
 
 var formdata_delete = [
   { fieldname: "testing",
     value: "failure"
   }
 ];
 
+var formdata_new = [
+  { fieldname: "new-field",
+    value: "new-value"
+  }
+]
 /*
  * Test phases
  */
 
 Phase('phase1', [
   [Formdata.add, formdata1],
   [Formdata.verify, formdata1],
   [Sync]
@@ -67,18 +77,21 @@ Phase('phase2', [
  * tests are disabled below.  See bug 568363.
  */
 
 Phase('phase3', [
   [Sync],
   [Formdata.delete, formdata_delete],
 //[Formdata.verifyNot, formdata_delete],
   [Formdata.verify, formdata2],
+  // add new data after the first Sync, ensuring the tracker works.
+  [Formdata.add, formdata_new],
   [Sync],
 ]);
 
 Phase('phase4', [
   [Sync],
   [Formdata.verify, formdata2],
+  [Formdata.verify, formdata_new],
 //[Formdata.verifyNot, formdata_delete]
 ]);
 
 
deleted file mode 100644
--- a/services/sync/tests/tps/test_privbrw_formdata.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * The list of phases mapped to their corresponding profiles.  The object
- * here must be in strict JSON format, as it will get parsed by the Python
- * testrunner (no single quotes, extra comma's, etc).
- */
-EnableEngines(["forms"]);
-
-var phases = { "phase1": "profile1",
-               "phase2": "profile2",
-               "phase3": "profile1",
-               "phase4": "profile2" };
-
-/*
- * Form data
- */
-
-// the form data to add to the browser
-var formdata1 = [
-   { fieldname: "name",
-     value: "xyz",
-     date: -1
-   },
-   { fieldname: "email",
-     value: "abc@gmail.com",
-     date: -2
-   },
-   { fieldname: "username",
-     value: "joe"
-   }
-];
-
-// the form data to add in private browsing mode
-var formdata2 = [
-   { fieldname: "password",
-     value: "secret",
-     date: -1
-   },
-   { fieldname: "city",
-     value: "mtview"
-   }
-];
-
-/*
- * Test phases
- */
-
-Phase('phase1', [
-  [Formdata.add, formdata1],
-  [Formdata.verify, formdata1],
-  [Sync]
-]);
-
-Phase('phase2', [
-  [Sync],
-  [Formdata.verify, formdata1]
-]);
-
-Phase('phase3', [
-  [Sync],
-  [Windows.add, { private: true }],
-  [Formdata.add, formdata2],
-  [Formdata.verify, formdata2],
-  [Sync],
-]);
-
-Phase('phase4', [
-  [Sync],
-  [Formdata.verify, formdata1],
-  [Formdata.verifyNot, formdata2]
-]);
--- a/services/sync/tests/unit/test_bookmark_validator.js
+++ b/services/sync/tests/unit/test_bookmark_validator.js
@@ -100,25 +100,16 @@ add_test(function test_isr_duplicatesAnd
     {id: 'A', type: 'folder', parentid: 'places', children: []},
     {type: 'folder', parentid: 'places', children: []}
   ]).problemData;
   equal(c.missingIDs, 1);
   deepEqual(c.duplicates, ['A']);
   run_next_test();
 });
 
-add_test(function test_isr_wrongParentName() {
-  let c = inspectServerRecords([
-    {id: 'A', type: 'folder', title: 'My Amazing Bookmarks', parentName: '', parentid: 'places', children: ['B']},
-    {id: 'B', type: 'bookmark', title: '', parentName: 'My Awesome Bookmarks', parentid: 'A'},
-  ]).problemData;
-  deepEqual(c.wrongParentName, ['B'])
-  run_next_test();
-});
-
 add_test(function test_isr_duplicateChildren()  {
   let c = inspectServerRecords([
     {id: 'A', type: 'folder', parentid: 'places', children: ['B', 'B']},
     {id: 'B', type: 'bookmark', parentid: 'A'},
   ]).problemData;
   deepEqual(c.duplicateChildren, ['A']);
   run_next_test();
 });
--- a/services/sync/tests/unit/test_service_sync_locked.js
+++ b/services/sync/tests/unit/test_service_sync_locked.js
@@ -26,12 +26,12 @@ function run_test() {
   // Avoid daily ping
   Svc.Prefs.set("lastPing", Math.floor(Date.now() / 1000));
 
   _("Check that sync will log appropriately if already in 'progress'.");
   Service._locked = true;
   Service.sync();
   Service._locked = false;
 
-  do_check_true(debug[debug.length - 2].startsWith("Exception: Could not acquire lock. Label: \"service.js: login\"."));
+  do_check_true(debug[debug.length - 2].startsWith("Exception calling WrappedLock: Could not acquire lock. Label: \"service.js: login\"."));
   do_check_eq(info[info.length - 1], "Cannot start sync: already syncing?");
 }
 
--- a/services/sync/tps/extensions/tps/resource/modules/forms.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/forms.jsm
@@ -8,158 +8,116 @@
   */
 
 var EXPORTED_SYMBOLS = ["FormData"];
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://tps/logger.jsm");
 
-var formService = Cc["@mozilla.org/satchel/form-history;1"]
-                  .getService(Ci.nsIFormHistory2);
+Cu.import("resource://gre/modules/FormHistory.jsm");
+Cu.import("resource://gre/modules/Log.jsm");
 
 /**
  * FormDB
  *
- * Helper object containing methods to interact with the moz_formhistory
- * SQLite table.
+ * Helper object containing methods to interact with the FormHistory module.
  */
 var FormDB = {
-  /**
-   * makeGUID
-   *
-   * Generates a brand-new globally unique identifier (GUID).  Borrowed
-   * from Weave's utils.js.
-   *
-   * @return the new guid
-   */
-  makeGUID: function makeGUID() {
-    // 70 characters that are not-escaped URL-friendly
-    const code =
-      "!()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
-
-    let guid = "";
-    let num = 0;
-    let val;
-
-    // Generate ten 70-value characters for a 70^10 (~61.29-bit) GUID
-    for (let i = 0; i < 10; i++) {
-      // Refresh the number source after using it a few times
-      if (i == 0 || i == 5)
-        num = Math.random();
-
-      // Figure out which code to use for the next GUID character
-      num *= 70;
-      val = Math.floor(num);
-      guid += code[val];
-      num -= val;
-    }
-
-    return guid;
+  _update(data) {
+    return new Promise((resolve, reject) => {
+      let handlers = {
+        handleError(error) {
+          Logger.logError("Error occurred updating form history: " + Log.exceptionStr(error));
+          reject(error);
+        },
+        handleCompletion(reason) {
+          resolve();
+        }
+      }
+      FormHistory.update(data, handlers);
+    });
   },
 
   /**
    * insertValue
    *
-   * Inserts the specified value for the specified fieldname into the
-   * moz_formhistory table.
+   * Adds the specified value for the specified fieldname into form history.
    *
    * @param fieldname The form fieldname to insert
    * @param value The form value to insert
    * @param us The time, in microseconds, to use for the lastUsed
    *        and firstUsed columns
-   * @return nothing
+   * @return Promise<undefined>
    */
-  insertValue: function (fieldname, value, us) {
-    let query = this.createStatement(
-      "INSERT INTO moz_formhistory " +
-      "(fieldname, value, timesUsed, firstUsed, lastUsed, guid) VALUES " +
-      "(:fieldname, :value, :timesUsed, :firstUsed, :lastUsed, :guid)");
-    query.params.fieldname = fieldname;
-    query.params.value = value;
-    query.params.timesUsed = 1;
-    query.params.firstUsed = us;
-    query.params.lastUsed = us;
-    query.params.guid = this.makeGUID();
-    query.execute();
-    query.reset();
+  insertValue(fieldname, value, us) {
+    let data = { op: "add", fieldname, value, timesUsed: 1,
+                 firstUsed: us, lastUsed: us }
+    return this._update(data);
   },
 
   /**
    * updateValue
    *
    * Updates a row in the moz_formhistory table with a new value.
    *
    * @param id The id of the row to update
    * @param newvalue The new value to set
-   * @return nothing
+   * @return Promise<undefined>
    */
-  updateValue: function (id, newvalue) {
-    let query = this.createStatement(
-      "UPDATE moz_formhistory SET value = :value WHERE id = :id");
-    query.params.id = id;
-    query.params.value = newvalue;
-    query.execute();
-    query.reset();
+  updateValue(id, newvalue) {
+    return this._update({ op: "update", guid: id, value: newvalue });
   },
 
   /**
    * getDataForValue
    *
    * Retrieves a set of values for a row in the database that
    * corresponds to the given fieldname and value.
    *
    * @param fieldname The fieldname of the row to query
    * @param value The value of the row to query
-   * @return null if no row is found with the specified fieldname and value,
-   *         or an object containing the row's id, lastUsed, and firstUsed
-   *         values
+   * @return Promise<null if no row is found with the specified fieldname and value,
+   *         or an object containing the row's guid, lastUsed, and firstUsed
+   *         values>
    */
-  getDataForValue: function (fieldname, value) {
-    let query = this.createStatement(
-      "SELECT id, lastUsed, firstUsed FROM moz_formhistory WHERE " +
-      "fieldname = :fieldname AND value = :value");
-    query.params.fieldname = fieldname;
-    query.params.value = value;
-    if (!query.executeStep())
-      return null;
-
-    return {
-      id: query.row.id,
-      lastUsed: query.row.lastUsed,
-      firstUsed: query.row.firstUsed
-    };
+  getDataForValue(fieldname, value) {
+    return new Promise((resolve, reject) => {
+      let result = null;
+      let handlers = {
+        handleResult(oneResult) {
+          if (result != null) {
+            reject("more than 1 result for this query");
+            return;
+          }
+          result = oneResult;
+        },
+        handleError(error) {
+          Logger.logError("Error occurred updating form history: " + Log.exceptionStr(error));
+          reject(error);
+        },
+        handleCompletion(reason) {
+          resolve(result);
+        }
+      }
+      FormHistory.search(["guid", "lastUsed", "firstUsed"], { fieldname }, handlers);
+    });
   },
 
   /**
-   * createStatement
+   * remove
    *
-   * Creates a statement from a SQL string.  This function is borrowed
-   * from Weave's forms.js.
+   * Removes the specified GUID from the database.
    *
-   * @param query The SQL query string
-   * @return the mozIStorageStatement created from the specified SQL
+   * @param guid The guid of the item to delete
+   * @return Promise<>
    */
-  createStatement: function createStatement(query) {
-    try {
-      // Just return the statement right away if it's okay
-      return formService.DBConnection.createStatement(query);
-    }
-    catch(ex) {
-      // Assume guid column must not exist yet, so add it with an index
-      formService.DBConnection.executeSimpleSQL(
-        "ALTER TABLE moz_formhistory ADD COLUMN guid TEXT");
-      formService.DBConnection.executeSimpleSQL(
-        "CREATE INDEX IF NOT EXISTS moz_formhistory_guid_index " +
-        "ON moz_formhistory (guid)");
-    }
-
-    // Try creating the query now that the column exists
-    return formService.DBConnection.createStatement(query);
-  }
+   remove(guid) {
+    return this._update({ op: "remove", guid });
+  },
 };
 
 /**
  * FormData class constructor
  *
  * Initializes instance properties.
  */
 function FormData(props, usSinceEpoch) {
@@ -199,63 +157,63 @@ FormData.prototype = {
    * add it.  Throws on error.
    *
    * @return nothing
    */
   Create: function() {
     Logger.AssertTrue(this.fieldname != null && this.value != null,
       "Must specify both fieldname and value");
 
-    let formdata = FormDB.getDataForValue(this.fieldname, this.value);
-    if (!formdata) {
-      // this item doesn't exist yet in the db, so we need to insert it
-      FormDB.insertValue(this.fieldname, this.value,
-                         this.hours_to_us(this.date));
-    }
-    else {
-      /* Right now, we ignore this case.  If bug 552531 is ever fixed,
-         we might need to add code here to update the firstUsed or
-         lastUsed fields, as appropriate.
-       */
-    }
+    return FormDB.getDataForValue(this.fieldname, this.value).then(formdata => {
+      if (!formdata) {
+        // this item doesn't exist yet in the db, so we need to insert it
+        return FormDB.insertValue(this.fieldname, this.value,
+                                  this.hours_to_us(this.date));
+      } else {
+        /* Right now, we ignore this case.  If bug 552531 is ever fixed,
+           we might need to add code here to update the firstUsed or
+           lastUsed fields, as appropriate.
+         */
+      }
+    });
   },
 
   /**
    * Find
    *
    * Attempts to locate an entry in the moz_formhistory database that
    * matches the fieldname and value for this FormData object.
    *
    * @return true if this entry exists in the database, otherwise false
    */
   Find: function() {
-    let formdata = FormDB.getDataForValue(this.fieldname, this.value);
-    let status = formdata != null;
-    if (status) {
-      /*
-      //form history dates currently not synced!  bug 552531
-      let us = this.hours_to_us(this.date);
-      status = Logger.AssertTrue(
-        us >= formdata.firstUsed && us <= formdata.lastUsed,
-        "No match for with that date value");
+    return FormDB.getDataForValue(this.fieldname, this.value).then(formdata => {
+      let status = formdata != null;
+      if (status) {
+        /*
+        //form history dates currently not synced!  bug 552531
+        let us = this.hours_to_us(this.date);
+        status = Logger.AssertTrue(
+          us >= formdata.firstUsed && us <= formdata.lastUsed,
+          "No match for with that date value");
 
-      if (status)
-      */
-        this.id = formdata.id;
-    }
-    return status;
+        if (status)
+        */
+          this.id = formdata.guid;
+      }
+      return status;
+    });
   },
 
   /**
    * Remove
    *
    * Removes the row represented by this FormData instance from the
    * moz_formhistory database.
    *
    * @return nothing
    */
   Remove: function() {
     /* Right now Weave doesn't handle this correctly, see bug 568363.
      */
-    formService.removeEntry(this.fieldname, this.value);
-    return true;
+    return FormDB.remove(this.id);
   },
 };
--- a/services/sync/tps/extensions/tps/resource/tps.jsm
+++ b/services/sync/tps/extensions/tps/resource/tps.jsm
@@ -77,17 +77,17 @@ const ACTIONS = [
   ACTION_SYNC_WIPE_REMOTE,
   ACTION_VERIFY,
   ACTION_VERIFY_NOT,
 ];
 
 const OBSERVER_TOPICS = ["fxaccounts:onlogin",
                          "fxaccounts:onlogout",
                          "private-browsing",
-                         "quit-application-requested",
+                         "profile-before-change",
                          "sessionstore-windows-restored",
                          "weave:engine:start-tracking",
                          "weave:engine:stop-tracking",
                          "weave:service:login:error",
                          "weave:service:setup-complete",
                          "weave:service:sync:finish",
                          "weave:service:sync:delayed",
                          "weave:service:sync:error",
@@ -161,17 +161,17 @@ var TPS = {
     try {
       Logger.logInfo("----------event observed: " + topic);
 
       switch(topic) {
         case "private-browsing":
           Logger.logInfo("private browsing " + data);
           break;
 
-        case "quit-application-requested":
+        case "profile-before-change":
           OBSERVER_TOPICS.forEach(function(topic) {
             Services.obs.removeObserver(this, topic);
           }, this);
 
           Logger.close();
 
           break;
 
@@ -362,27 +362,28 @@ var TPS = {
   HandleForms: function (data, action) {
     this.shouldValidateForms = true;
     for (let datum of data) {
       Logger.logInfo("executing action " + action.toUpperCase() +
                      " on form entry " + JSON.stringify(datum));
       let formdata = new FormData(datum, this._usSinceEpoch);
       switch(action) {
         case ACTION_ADD:
-          formdata.Create();
+          Async.promiseSpinningly(formdata.Create());
           break;
         case ACTION_DELETE:
-          formdata.Remove();
+          Async.promiseSpinningly(formdata.Remove());
           break;
         case ACTION_VERIFY:
-          Logger.AssertTrue(formdata.Find(), "form data not found");
+          Logger.AssertTrue(Async.promiseSpinningly(formdata.Find()),
+                            "form data not found");
           break;
         case ACTION_VERIFY_NOT:
-          Logger.AssertTrue(!formdata.Find(),
-            "form data found, but it shouldn't be present");
+          Logger.AssertTrue(!Async.promiseSpinningly(formdata.Find()),
+                            "form data found, but it shouldn't be present");
           break;
         default:
           Logger.AssertTrue(false, "invalid action: " + action);
       }
     }
     Logger.logPass("executing action " + action.toUpperCase() +
                    " on formdata");
   },
@@ -586,17 +587,24 @@ var TPS = {
 
   Cleanup() {
     try {
       this.WipeServer();
     } catch (ex) {
       Logger.logError("Failed to wipe server: " + Log.exceptionStr(ex));
     }
     try {
-      Authentication.signOut();
+      if (Authentication.isLoggedIn) {
+        // signout and wait for Sync to completely reset itself.
+        Logger.logInfo("signing out");
+        let waiter = this.createEventWaiter("weave:service:start-over:finish");
+        Authentication.signOut();
+        waiter();
+        Logger.logInfo("signout complete");
+      }
     } catch (e) {
       Logger.logError("Failed to sign out: " + Log.exceptionStr(e));
     }
   },
 
   /**
    * Use Sync's bookmark validation code to see if we've corrupted the tree.
    */
@@ -628,25 +636,16 @@ var TPS = {
       let validator = new BookmarkValidator();
       let {problemData} = validator.compareServerWithClient(serverRecords, clientTree);
 
       for (let {name, count} of problemData.getSummary()) {
         // Exclude mobile showing up on the server hackily so that we don't
         // report it every time, see bug 1273234 and 1274394 for more information.
         if (name === "serverUnexpected" && problemData.serverUnexpected.indexOf("mobile") >= 0) {
           --count;
-        } else if (name === "differences") {
-          // Also exclude errors in parentName/wrongParentName (bug 1276969) for
-          // the same reason.
-          let newCount = problemData.differences.filter(diffInfo =>
-            !diffInfo.differences.every(diff =>
-              diff === "parentName")).length
-          count = newCount;
-        } else if (name === "wrongParentName") {
-          continue;
         }
         if (count) {
           // Log this out before we assert. This is useful in the context of TPS logs, since we
           // can see the IDs in the test files.
           Logger.logInfo(`Validation problem: "${name}": ${JSON.stringify(problemData[name])}`);
         }
         Logger.AssertEqual(count, 0, `Bookmark validation error of type ${name}`);
       }
@@ -696,18 +695,18 @@ var TPS = {
     let serverRecordDumpStr;
     let clientRecordDumpStr;
     try {
       Logger.logInfo("About to perform form validation");
       let engine = Weave.Service.engineManager.get("forms");
       let validator = new FormValidator();
       let serverRecords = validator.getServerItems(engine);
       let clientRecords = Async.promiseSpinningly(validator.getClientItems());
-      clientRecordDumpStr = JSON.stringify(clientRecords);
-      serverRecordDumpStr = JSON.stringify(serverRecords);
+      clientRecordDumpStr = JSON.stringify(clientRecords, undefined, 2);
+      serverRecordDumpStr = JSON.stringify(serverRecords, undefined, 2);
       let { problemData } = validator.compareClientWithServer(clientRecords, serverRecords);
       for (let { name, count } of problemData.getSummary()) {
         if (count) {
           Logger.logInfo(`Validation problem: "${name}": ${JSON.stringify(problemData[name])}`);
         }
         Logger.AssertEqual(count, 0, `Form validation error of type ${name}`);
       }
     } catch (e) {
@@ -971,34 +970,66 @@ var TPS = {
     Cu.import('resource://mozmill/modules/frame.js', frame);
     frame.events.addListener('setTest', this.MozmillSetTestListener.bind(this));
     frame.events.addListener('endTest', this.MozmillEndTestListener.bind(this));
     this.StartAsyncOperation();
     frame.runTestFile(mozmillfile.path, null);
   },
 
   /**
+   * Return an object that when called, will block until the named event
+   * is observed. This is similar to waitForEvent, although is typically safer
+   * if you need to do some other work that may make the event fire.
+   *
+   * eg:
+   *    doSomething(); // causes the event to be fired.
+   *    waitForEvent("something");
+   * is risky as the call to doSomething may trigger the event before the
+   * waitForEvent call is made. Contrast with:
+   *
+   *   let waiter = createEventWaiter("something"); // does *not* block.
+   *   doSomething(); // causes the event to be fired.
+   *   waiter(); // will return as soon as the event fires, even if it fires
+   *             // before this function is called.
+   *
+   * @param aEventName
+   *        String event to wait for.
+   */
+  createEventWaiter(aEventName) {
+    Logger.logInfo("Setting up wait for " + aEventName + "...");
+    let cb = Async.makeSpinningCallback();
+    Svc.Obs.add(aEventName, cb);
+    return function() {
+      try {
+        cb.wait();
+      } finally {
+        Svc.Obs.remove(aEventName, cb);
+        Logger.logInfo(aEventName + " observed!");
+      }
+    }
+  },
+
+
+  /**
    * Synchronously wait for the named event to be observed.
    *
    * When the event is observed, the function will wait an extra tick before
    * returning.
    *
+   * Note that in general, you should probably use createEventWaiter unless you
+   * are 100% sure that the event being waited on can only be sent after this
+   * call adds the listener.
+   *
    * @param aEventName
    *        String event to wait for.
    */
   waitForEvent: function waitForEvent(aEventName) {
-    Logger.logInfo("Waiting for " + aEventName + "...");
-    let cb = Async.makeSpinningCallback();
-    Svc.Obs.add(aEventName, cb);
-    cb.wait();
-    Svc.Obs.remove(aEventName, cb);
-    Logger.logInfo(aEventName + " observed!");
+    this.createEventWaiter(aEventName)();
   },
 
-
   /**
    * Waits for Sync to logged in before returning
    */
   waitForSetupComplete: function waitForSetup() {
     if (!this._setupComplete) {
       this.waitForEvent("weave:service:setup-complete");
     }
   },
--- a/taskcluster/ci/build/linux.yml
+++ b/taskcluster/ci/build/linux.yml
@@ -18,20 +18,22 @@ linux64/opt:
             - builds/releng_base_linux_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         tooltool-downloads: public
         need-xvfb: true
 
 linux64/pgo:
-    description: "Linux64 Opt PGO"
+    description: "Linux64 PGO"
     index:
         product: firefox
-        job-name: linux64-pgo-opt
+        job-name:
+            buildbot: linux64-pgo
+            gecko-v2: linux64-pgo
     treeherder:
         platform: linux64/pgo
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
         implementation: docker-worker
         max-run-time: 36000
--- a/taskcluster/taskgraph/transforms/gecko_v2_whitelist.py
+++ b/taskcluster/taskgraph/transforms/gecko_v2_whitelist.py
@@ -31,17 +31,17 @@ JOB_NAME_WHITELIST = set([
     'linux64-artifact-opt',
     'linux64-asan-debug',
     'linux64-asan-opt',
     'linux64-ccov-opt',
     'linux64-debug',
     'linux64-jsdcov-opt',
     'linux64-l10n-opt',
     'linux64-opt',
-    'linux64-pgo-opt',
+    'linux64-pgo',
     'linux64-st-an-opt',
     'linux64-valgrind-opt',
     'linux-debug',
     'linux-opt',
     'macosx64-debug',
     'macosx64-opt',
     'macosx64-st-an-opt',
     'mulet-dbg',
deleted file mode 100644
--- a/testing/marionette/harness/marionette/tests/print-manifest-dirs.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# 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/.
-
-from manifestparser import TestManifest
-import os.path
-import sys
-
-def print_test_dirs(topsrcdir, manifest_file):
-    """
-    Simple routine which prints the paths of directories specified
-    in a Marionette manifest, relative to topsrcdir.  This does not recurse 
-    into manifests, as we currently have no need for that.
-    """
-
-    dirs = set()
-    # output the directory of this (parent) manifest
-    topsrcdir = os.path.abspath(topsrcdir)
-    scriptdir = os.path.abspath(os.path.dirname(__file__))
-    dirs.add(scriptdir[len(topsrcdir) + 1:])
-
-    # output the directories of all the other manifests
-    manifest = TestManifest()
-    manifest.read(manifest_file)
-    for i in manifest.get():
-        d = os.path.dirname(i['manifest'])[len(topsrcdir) + 1:]
-        dirs.add(d)
-    for path in dirs:
-        path = path.replace('\\', '/')
-        print path
-
-if __name__ == '__main__':
-    if len(sys.argv) < 3:
-        print >>sys.stderr, "Usage: %s topsrcdir manifest.ini" % sys.argv[0]
-        sys.exit(1)
-
-    print_test_dirs(sys.argv[1], sys.argv[2])
-
--- a/testing/marionette/harness/marionette/tests/unit/test_window_management.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_window_management.py
@@ -32,35 +32,38 @@ if (win != null)
   win.close();
 """)
         self.marionette.set_context("content")
 
     def test_windows(self):
         orig_win = self.marionette.current_window_handle
         orig_available = self.marionette.window_handles
         self.open_new_window()
-        #assert we're still in the original window
+        # assert we're still in the original window
         self.assertEqual(self.marionette.current_window_handle, orig_win)
-        now_available = self.marionette.window_handles
-        #assert we can find the new window
+        # assert we can find the new window
         Wait(self.marionette).until(
-            lambda _: len(now_available) == len(orig_available) + 1,
+            lambda _: len(self.marionette.window_handles) == len(orig_available) + 1,
             message="The new window has not been opened.")
-        #assert that our window is there
-        self.assertTrue(orig_win in now_available)
+        # assert that our window is there
+        now_available = self.marionette.window_handles
+        self.assertIn(orig_win, now_available)
         new_win = None
         for win in now_available:
             if win != orig_win:
-                new_win = orig_win
-        #switch to another window
+                new_win = win
+        # switch to another window
         self.marionette.switch_to_window(new_win)
         self.assertEqual(self.marionette.current_window_handle, new_win)
-        #switch back
+        self.assertNotEqual(self.marionette.current_window_handle, orig_win)
+        # switch back
         self.marionette.switch_to_window(orig_win)
+        self.assertEqual(self.marionette.current_window_handle, orig_win)
         self.close_new_window()
+        self.assertNotIn(new_win, self.marionette.window_handles)
         self.assertEqual(self.marionette.current_window_handle, orig_win)
         self.assertEqual(len(self.marionette.window_handles), len(orig_available))
 
     def testShouldLoadAWindowAndThenCloseIt(self):
         test_html = self.marionette.absolute_url("test_windows.html")
         self.marionette.navigate(test_html)
         current = self.marionette.current_window_handle
 
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -1590,16 +1590,24 @@ SpecialPowersAPI.prototype = {
       addSystemEventListener(target, type, listener, useCapture);
   },
   removeSystemEventListener: function(target, type, listener, useCapture) {
     Cc["@mozilla.org/eventlistenerservice;1"].
       getService(Ci.nsIEventListenerService).
       removeSystemEventListener(target, type, listener, useCapture);
   },
 
+  // helper method to check if the event is consumed by either default group's
+  // event listener or system group's event listener.
+  defaultPreventedInAnyGroup: function(event) {
+    // FYI: Event.defaultPrevented returns false in content context if the
+    //      event is consumed only by system group's event listeners.
+    return event.defaultPrevented;
+  },
+
   getDOMRequestService: function() {
     var serv = Services.DOMRequest;
     var res = {};
     var props = ["createRequest", "createCursor", "fireError", "fireSuccess",
                  "fireDone", "fireDetailedError"];
     for (var i in props) {
       let prop = props[i];
       res[prop] = function() { return serv[prop].apply(serv, arguments) };
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -177,17 +177,16 @@ PKG_STAGE = $(DIST)/test-stage
 
 stage-all: \
   stage-config \
   stage-mach \
   stage-extensions \
   stage-mochitest \
   stage-jstests \
   stage-jetpack \
-  stage-marionette \
   stage-luciddream \
   test-packages-manifest \
   $(NULL)
 ifdef MOZ_WEBRTC
 stage-all: stage-steeplechase
 endif
 
 ifdef COMPILE_ENVIRONMENT
@@ -326,34 +325,16 @@ stage-steeplechase: make-stage-dir
 	cp -RL $(DIST)/xpi-stage/specialpowers $(PKG_STAGE)/steeplechase
 	cp -RL $(topsrcdir)/testing/profiles/prefs_general.js $(PKG_STAGE)/steeplechase
 
 LUCIDDREAM_DIR=$(PKG_STAGE)/luciddream
 stage-luciddream: make-stage-dir
 	$(NSINSTALL) -D $(LUCIDDREAM_DIR)
 	@(cd $(topsrcdir)/testing/luciddream && tar $(TAR_CREATE_FLAGS) - *) | (cd $(LUCIDDREAM_DIR)/ && tar -xf -)
 
-MARIONETTE_DIR=$(PKG_STAGE)/marionette
-stage-marionette: make-stage-dir
-	$(NSINSTALL) -D $(MARIONETTE_DIR)/tests
-	$(NSINSTALL) -D $(MARIONETTE_DIR)/client
-	@(cd $(topsrcdir)/testing/marionette/harness && tar --exclude marionette/tests $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/ && tar -xf -)
-	@(cd $(topsrcdir)/testing/marionette/client && tar $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/client && tar -xf -)
-	cp $(topsrcdir)/testing/marionette/mach_test_package_commands.py $(MARIONETTE_DIR)
-	$(PYTHON) $(topsrcdir)/testing/marionette/harness/marionette/tests/print-manifest-dirs.py \
-          $(topsrcdir) \
-          $(topsrcdir)/testing/marionette/harness/marionette/tests/unit-tests.ini \
-          | (cd $(topsrcdir) && xargs tar $(TAR_CREATE_FLAGS) -) \
-          | (cd $(MARIONETTE_DIR)/tests && tar -xf -)
-	$(PYTHON) $(topsrcdir)/testing/marionette/harness/marionette/tests/print-manifest-dirs.py \
-          $(topsrcdir) \
-          $(topsrcdir)/testing/marionette/harness/marionette/tests/webapi-tests.ini \
-          | (cd $(topsrcdir) && xargs tar $(TAR_CREATE_FLAGS) -) \
-          | (cd $(MARIONETTE_DIR)/tests && tar -xf -)
-
 stage-instrumentation-tests: make-stage-dir
 	$(MAKE) -C $(DEPTH)/testing/instrumentation stage-package
 
 TEST_EXTENSIONS := \
     specialpowers@mozilla.org.xpi \
 	$(NULL)
 
 stage-extensions: make-stage-dir
@@ -371,14 +352,13 @@ stage-extensions: make-stage-dir
   make-stage-dir \
   stage-all \
   stage-b2g \
   stage-config \
   stage-mochitest \
   stage-jstests \
   stage-android \
   stage-jetpack \
-  stage-marionette \
   stage-steeplechase \
   stage-instrumentation-tests \
   stage-luciddream \
   test-packages-manifest \
   $(NULL)
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -281,21 +281,20 @@ class XPCShellTestThread(Thread):
         We can sometimes get here before the process has terminated, which would
         cause removeDir() to fail - so check for the process and kill it if needed.
         """
         if proc and self.poll(proc) is None:
             self.kill(proc)
             message = "%s | Process still running after test!" % self.test_object['id']
             if self.retry:
                 self.log.info(message)
-                self.log_full_output(self.output_lines)
                 return
 
             self.log.error(message)
-            self.log_full_output(self.output_lines)
+            self.log_full_output()
             self.failCount = 1
 
     def testTimeout(self, proc):
         if self.test_object['expected'] == 'pass':
             expected = 'PASS'
         else:
             expected = 'FAIL'
 
@@ -303,17 +302,17 @@ class XPCShellTestThread(Thread):
             self.log.test_end(self.test_object['id'], 'TIMEOUT',
                               expected='TIMEOUT',
                               message="Test timed out")
         else:
             self.failCount = 1
             self.log.test_end(self.test_object['id'], 'TIMEOUT',
                               expected=expected,
                               message="Test timed out")
-            self.log_full_output(self.output_lines)
+            self.log_full_output()
 
         self.done = True
         self.timedout = True
         self.killTimeout(proc)
         self.log.info("xpcshell return code: %s" % self.getReturnCode(proc))
         self.postCheck(proc)
         self.clean_temp_dirs(self.test_object['path'])
 
@@ -524,33 +523,32 @@ class XPCShellTestThread(Thread):
             if 'message' in line:
                 line['message'] = self.fix_text_output(line['message'])
             if 'xpcshell_process' in line:
                 line['thread'] =  ' '.join([current_thread().name, line['xpcshell_process']])
             else:
                 line['thread'] = current_thread().name
             self.log.log_raw(line)
 
-    def log_full_output(self, output):
-        """Log output any buffered output from the test process"""
-        if not output:
+    def log_full_output(self):
+        """Logs any buffered output from the test process, and clears the buffer."""
+        if not self.output_lines:
             return
         self.log.info(">>>>>>>")
-        for line in output:
+        for line in self.output_lines:
             self.log_line(line)
         self.log.info("<<<<<<<")
+        self.output_lines = []
 
     def report_message(self, message):
         """Stores or logs a json log message in mozlog format."""
         if self.verbose:
             self.log_line(message)
         else:
-            # Tests eligible to retry will never dump their buffered output.
-            if not self.retry:
-                self.output_lines.append(message)
+            self.output_lines.append(message)
 
     def process_line(self, line_string):
         """ Parses a single line of output, determining its significance and
         reporting a message.
         """
         if not line_string.strip():
             return
 
@@ -741,49 +739,52 @@ class XPCShellTestThread(Thread):
             if status != expected:
                 if self.retry:
                     self.log.test_end(name, status, expected=status,
                                       message="Test failed or timed out, will retry")
                     self.clean_temp_dirs(path)
                     return
 
                 self.log.test_end(name, status, expected=expected, message=message)
-                self.log_full_output(self.output_lines)
+                self.log_full_output()
 
                 self.failCount += 1
 
                 if self.failureManifest:
                     with open(self.failureManifest, 'a') as f:
                         f.write('[%s]\n' % self.test_object['path'])
                         for k, v in self.test_object.items():
                             f.write('%s = %s\n' % (k, v))
 
             else:
                 # If TSan reports a race, dump the output, else we can't
                 # diagnose what the problem was.  See comments above about
                 # the significance of TSAN_EXIT_CODE_WITH_RACES.
                 if self.usingTSan and return_code == TSAN_EXIT_CODE_WITH_RACES:
-                    self.log_full_output(self.output_lines)
+                    self.log_full_output()
 
                 self.log.test_end(name, status, expected=expected, message=message)
                 if self.verbose:
-                    self.log_full_output(self.output_lines)
+                    self.log_full_output()
 
                 self.retry = False
 
                 if expect_pass:
                     self.passCount = 1
                 else:
                     self.todoCount = 1
 
             if self.checkForCrashes(self.tempDir, self.symbolsPath, test_name=name):
                 if self.retry:
                     self.clean_temp_dirs(path)
                     return
 
+                # If we assert during shutdown there's a chance the test has passed
+                # but we haven't logged full output, so do so here.
+                self.log_full_output()
                 self.failCount = 1
 
             if self.logfiles and process_output:
                 self.createLogFile(name, process_output)
 
         finally:
             self.postCheck(proc)
             self.clean_temp_dirs(path)
--- a/toolkit/components/autocomplete/nsAutoCompleteController.cpp
+++ b/toolkit/components/autocomplete/nsAutoCompleteController.cpp
@@ -1391,25 +1391,33 @@ nsAutoCompleteController::EnterMatch(boo
     bool completeSelection;
     input->GetCompleteSelectedIndex(&completeSelection);
 
     int32_t selectedIndex;
     popup->GetSelectedIndex(&selectedIndex);
     if (selectedIndex >= 0) {
       nsAutoString inputValue;
       input->GetTextValue(inputValue);
-      bool defaultCompleted = mDefaultIndexCompleted &&
-                              inputValue.Equals(mPlaceholderCompletionString,
-                                                nsCaseInsensitiveStringComparator());
-      if (aIsPopupSelection || (!completeSelection && !defaultCompleted)) {
+      if (aIsPopupSelection || !completeSelection) {
         // We need to fill-in the value if:
-        //  * completeselectedindex is false and we didn't defaultComplete
+        //  * completeselectedindex is false
         //  * A row in the popup was confirmed
+        //
+        // TODO: This is not totally correct, cause it will also confirm
+        // a result selected with a simple mouseover, that could also have
+        // happened accidentally, maybe touching a touchpad.
+        // The reason is that autocomplete.xml sets selectedIndex on mousemove
+        // making impossible, in the !completeSelection case, to distinguish if
+        // the user wanted to confirm autoFill or the popup entry.
+        // The solution may be to change autocomplete.xml to set selectedIndex
+        // only on popupClick, but that requires changing the selection behavior.
         GetResultValueAt(selectedIndex, true, value);
-      } else if (defaultCompleted) {
+      } else if (mDefaultIndexCompleted &&
+                 inputValue.Equals(mPlaceholderCompletionString,
+                                   nsCaseInsensitiveStringComparator())) {
         // We also need to fill-in the value if the default index completion was
         // confirmed, though we cannot use the selectedIndex cause the selection
         // may have been changed by the mouse in the meanwhile.
         GetFinalDefaultCompleteValue(value);
       } else if (mCompletedSelectionIndex != -1) {
         // If completeselectedindex is true, and EnterMatch was not invoked by
         // mouse-clicking a match (for example the user pressed Enter),
         // don't fill in the value as it will have already been filled in as
@@ -1585,82 +1593,68 @@ nsAutoCompleteController::ProcessResult(
     }
   }
   // When found the result should have the same index as the search.
   MOZ_ASSERT_IF(mResults.IndexOf(aResult) != -1,
                 mResults.IndexOf(aResult) == aSearchIndex);
   MOZ_ASSERT(mResults.Count() >= aSearchIndex + 1,
              "aSearchIndex should always be valid for mResults");
 
-  bool isTypeAheadResult = false;
-  aResult->GetTypeAheadResult(&isTypeAheadResult);
-
-  if (!isTypeAheadResult) {
-    uint32_t oldRowCount = mRowCount;
-    // If the search failed, increase the match count to include the error
-    // description.
-    if (searchResult == nsIAutoCompleteResult::RESULT_FAILURE) {
-      nsAutoString error;
-      aResult->GetErrorDescription(error);
-      if (!error.IsEmpty()) {
-        ++mRowCount;
-        if (mTree) {
-          mTree->RowCountChanged(oldRowCount, 1);
-        }
+  uint32_t oldRowCount = mRowCount;
+  // If the search failed, increase the match count to include the error
+  // description.
+  if (searchResult == nsIAutoCompleteResult::RESULT_FAILURE) {
+    nsAutoString error;
+    aResult->GetErrorDescription(error);
+    if (!error.IsEmpty()) {
+      ++mRowCount;
+      if (mTree) {
+        mTree->RowCountChanged(oldRowCount, 1);
       }
-    } else if (searchResult == nsIAutoCompleteResult::RESULT_SUCCESS ||
-               searchResult == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
-      // Increase the match count for all matches in this result.
-      uint32_t totalMatchCount = 0;
-      for (uint32_t i = 0; i < mResults.Length(); i++) {
-        nsIAutoCompleteResult* result = mResults.SafeObjectAt(i);
-        if (result) {
-          // not all results implement this, so it can likely fail.
-          bool typeAhead = false;
-          result->GetTypeAheadResult(&typeAhead);
-          if (!typeAhead) {
-            uint32_t matchCount = 0;
-            result->GetMatchCount(&matchCount);
-            totalMatchCount += matchCount;
-          }
-        }
-      }
-      uint32_t delta = totalMatchCount - oldRowCount;
-
-      mRowCount += delta;
-      if (mTree) {
-        mTree->RowCountChanged(oldRowCount, delta);
-      }
-    }
-
-    // Try to autocomplete the default index for this search.
-    // Do this before invalidating so the binding knows about it.
-    CompleteDefaultIndex(aSearchIndex);
-
-    // Refresh the popup view to display the new search results
-    nsCOMPtr<nsIAutoCompletePopup> popup;
-    input->GetPopup(getter_AddRefs(popup));
-    NS_ENSURE_TRUE(popup != nullptr, NS_ERROR_FAILURE);
-    popup->Invalidate(nsIAutoCompletePopup::INVALIDATE_REASON_NEW_RESULT);
-
-    uint32_t minResults;
-    input->GetMinResultsForPopup(&minResults);
-
-    // Make sure the popup is open, if necessary, since we now have at least one
-    // search result ready to display. Don't force the popup closed if we might
-    // get results in the future to avoid unnecessarily canceling searches.
-    if (mRowCount || !minResults) {
-      OpenPopup();
-    } else if (mSearchesOngoing == 0) {
-      ClosePopup();
     }
   } else if (searchResult == nsIAutoCompleteResult::RESULT_SUCCESS ||
              searchResult == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
-    // Try to autocomplete the default index for this search.
-    CompleteDefaultIndex(aSearchIndex);
+    // Increase the match count for all matches in this result.
+    uint32_t totalMatchCount = 0;
+    for (uint32_t i = 0; i < mResults.Length(); i++) {
+      nsIAutoCompleteResult* result = mResults.SafeObjectAt(i);
+      if (result) {
+        uint32_t matchCount = 0;
+        result->GetMatchCount(&matchCount);
+        totalMatchCount += matchCount;
+      }
+    }
+    uint32_t delta = totalMatchCount - oldRowCount;
+
+    mRowCount += delta;
+    if (mTree) {
+      mTree->RowCountChanged(oldRowCount, delta);
+    }
+  }
+
+  // Try to autocomplete the default index for this search.
+  // Do this before invalidating so the binding knows about it.
+  CompleteDefaultIndex(aSearchIndex);
+
+  // Refresh the popup view to display the new search results
+  nsCOMPtr<nsIAutoCompletePopup> popup;
+  input->GetPopup(getter_AddRefs(popup));
+  NS_ENSURE_TRUE(popup != nullptr, NS_ERROR_FAILURE);
+  popup->Invalidate(nsIAutoCompletePopup::INVALIDATE_REASON_NEW_RESULT);
+
+  uint32_t minResults;
+  input->GetMinResultsForPopup(&minResults);
+
+  // Make sure the popup is open, if necessary, since we now have at least one
+  // search result ready to display. Don't force the popup closed if we might
+  // get results in the future to avoid unnecessarily canceling searches.
+  if (mRowCount || !minResults) {
+    OpenPopup();
+  } else if (mSearchesOngoing == 0) {
+    ClosePopup();
   }
 
   return NS_OK;
 }
 
 nsresult
 nsAutoCompleteController::PostSearchCleanup()
 {
@@ -1992,30 +1986,24 @@ nsAutoCompleteController::RowIndexToSear
   // until we find the given row
   for (uint32_t i = 0; i < mSearches.Length(); ++i) {
     nsIAutoCompleteResult *result = mResults.SafeObjectAt(i);
     if (!result)
       continue;
 
     uint32_t rowCount = 0;
 
-    // Skip past the result completely if it is marked as hidden
-    bool isTypeAheadResult = false;
-    result->GetTypeAheadResult(&isTypeAheadResult);
+    uint16_t searchResult;
+    result->GetSearchResult(&searchResult);
 
-    if (!isTypeAheadResult) {
-      uint16_t searchResult;
-      result->GetSearchResult(&searchResult);
-
-      // Find out how many results were provided by the
-      // current nsIAutoCompleteSearch.
-      if (searchResult == nsIAutoCompleteResult::RESULT_SUCCESS ||
-          searchResult == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
-        result->GetMatchCount(&rowCount);
-      }
+    // Find out how many results were provided by the
+    // current nsIAutoCompleteSearch.
+    if (searchResult == nsIAutoCompleteResult::RESULT_SUCCESS ||
+        searchResult == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
+      result->GetMatchCount(&rowCount);
     }
 
     // If the given row index is within the results range
     // of the current nsIAutoCompleteSearch then return the
     // search index and sub-index into the results array
     if ((rowCount != 0) && (index + rowCount-1 >= (uint32_t) aRowIndex)) {
       *aSearchIndex = i;
       *aItemIndex = aRowIndex - index;
--- a/toolkit/components/autocomplete/nsAutoCompleteSimpleResult.cpp
+++ b/toolkit/components/autocomplete/nsAutoCompleteSimpleResult.cpp
@@ -38,18 +38,17 @@ struct AutoCompleteSimpleResultMatch
   nsString mImage;
   nsString mStyle;
   nsString mFinalCompleteValue;
   nsString mLabel;
 };
 
 nsAutoCompleteSimpleResult::nsAutoCompleteSimpleResult() :
   mDefaultIndex(-1),
-  mSearchResult(RESULT_NOMATCH),
-  mTypeAheadResult(false)
+  mSearchResult(RESULT_NOMATCH)
 {
 }
 
 nsresult
 nsAutoCompleteSimpleResult::AppendResult(nsIAutoCompleteResult* aResult)
 {
   nsAutoString searchString;
   nsresult rv = aResult->GetSearchString(searchString);
@@ -62,22 +61,16 @@ nsAutoCompleteSimpleResult::AppendResult
   mSearchResult = searchResult;
 
   nsAutoString errorDescription;
   if (NS_SUCCEEDED(aResult->GetErrorDescription(errorDescription)) &&
       !errorDescription.IsEmpty()) {
     mErrorDescription = errorDescription;
   }
 
-  bool typeAheadResult = false;
-  if (NS_SUCCEEDED(aResult->GetTypeAheadResult(&typeAheadResult)) &&
-      typeAheadResult) {
-    mTypeAheadResult = typeAheadResult;
-  }
-
   int32_t defaultIndex = -1;
   if (NS_SUCCEEDED(aResult->GetDefaultIndex(&defaultIndex)) &&
       defaultIndex >= 0) {
     mDefaultIndex = defaultIndex;
   }
 
   nsCOMPtr<nsIAutoCompleteSimpleResult> simpleResult =
     do_QueryInterface(aResult);
@@ -168,30 +161,16 @@ nsAutoCompleteSimpleResult::GetErrorDesc
 NS_IMETHODIMP
 nsAutoCompleteSimpleResult::SetErrorDescription(
                                              const nsAString &aErrorDescription)
 {
   mErrorDescription.Assign(aErrorDescription);
   return NS_OK;