Implement CSS revert keyword.

The only fishy bit is the animation stuff. In particular, there are two places
where we just mint the revert behavior:

 * When serializing web-animations keyframes (the custom properties stuff in
   declaration_block.rs). That codepath is already not sound and I wanted to
   get rid of it in bug 1501530, but what do I know.

 * When getting an animation value from a property declaration. At that point
   we no longer have the CSS rules that apply to the element to compute the
   right revert value handy. It'd also use the wrong style anyway, I think,
   given the way StyleBuilder::for_animation works.

   We _could_ probably get them out of somewhere, but it seems like a whole lot
   of code reinventing the wheel which is probably not useful, and that Blink
   and WebKit just cannot implement either since they don't have a rule tree,
   so it just doesn't seem worth the churn.

The custom properties code looks a bit different in order to minimize hash
lookups in the common case. FWIW, `revert` for custom properties doesn't seem
very useful either, but oh well.

Differential Revision: https://phabricator.services.mozilla.com/D21877

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1215878
gecko-commit: 1ae26ce1cf090db6b0b19ea7d7eccd42373dd5fa
gecko-integration-branch: central
gecko-reviewers: heycam, birtles
diff --git a/css/css-cascade/revert-val-002.html b/css/css-cascade/revert-val-002.html
new file mode 100644
index 0000000..d145ea4
--- /dev/null
+++ b/css/css-cascade/revert-val-002.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Cascade: 'revert' keyword interaction with !important</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-cascade/#default">
+<link rel="match" href="reference/ref-filled-green-100px-square.xht">
+<style>
+#outer {
+  background-color: red;
+  width: 100px;
+  height: 100px;
+  overflow: hidden;
+}
+#inner {
+  /* This should win over `revert` */
+  display: block !important;
+}
+#inner {
+  color: green;
+  background-color: green;
+  display: revert;
+}
+</style>
+</head>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div id="outer">
+    <span id="inner">
+      This<br>
+      is<br>
+      filler<br>
+      text.<br>
+      This<br>
+      is<br>
+      filler<br>
+      text.
+    </span>
+  </div>
+</body>
+</html>
diff --git a/css/css-cascade/revert-val-003.html b/css/css-cascade/revert-val-003.html
new file mode 100644
index 0000000..b819eb0
--- /dev/null
+++ b/css/css-cascade/revert-val-003.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Cascade: 'revert' keyword in transition</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-cascade/#default">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+html, body { margin: 0 }
+h1 {
+  margin: 0;
+  transition: margin 10s;
+  transition-delay: -5s; /* So we can expect it to be half-way the transition when toggling the property */
+}
+</style>
+<h1>This is a header that should get some margin</h1>
+<script>
+test(function() {
+  const el = document.querySelector("h1");
+  const cs = getComputedStyle(el);
+  assert_equals(cs.marginTop, "0px", "Margin before transition");
+  el.style.margin = "revert";
+  const midTransition = cs.marginTop;
+  assert_not_equals(midTransition, "0px", "Margin mid transition");
+  el.style.transition = "none";
+  assert_not_equals(cs.marginTop, midTransition, "Default margin");
+}, "revert works with transitions");
+</script>
diff --git a/css/css-variables/variable-definition-keywords.html b/css/css-variables/variable-definition-keywords.html
index 6cba261..7e88761 100644
--- a/css/css-variables/variable-definition-keywords.html
+++ b/css/css-variables/variable-definition-keywords.html
@@ -33,19 +33,25 @@
         <div id="unsetTest" style="--var: unset;"></div>
     </div>
 
+    <div id="revertParent" style="--var: 20px;">
+        <div id="revertTest" style="--var: revert;"></div>
+    </div>
+
     <script type="text/javascript">
         "use strict";
 
         let computedStyle = [
             { elementId: "inheritTest", property: "--var", expectedValue: "20px", testName: "computed style inherit" },
             { elementId: "initialTest", property: "--var", expectedValue: "", testName: "computed style initial" },
-            { elementId: "unsetTest", property: "--var", expectedValue: "20px", testName: "computed style unset" }
+            { elementId: "unsetTest", property: "--var", expectedValue: "20px", testName: "computed style unset" },
+            { elementId: "revertTest", property: "--var", expectedValue: "20px", testName: "computed style revert" }
         ];
 
         let specifiedStyle = [
             { elementId: "inheritTest", property: "--var", expectedValue: "inherit", testName: "specified style inherit" },
             { elementId: "initialTest", property: "--var", expectedValue: "initial", testName: "specified style initial" },
-            { elementId: "unsetTest", property: "--var", expectedValue: "unset", testName: "specified style unset" }
+            { elementId: "unsetTest", property: "--var", expectedValue: "unset", testName: "specified style unset" },
+            { elementId: "revertTest", property: "--var", expectedValue: "revert", testName: "specified style revert" }
         ];
 
         computedStyle.forEach(function (csTest) {