Merge pull request #8343 from w3c/sync_34565dc4fd5c10b3e12838d6dfb2ca7a7d800ee9

Use for...of instead of forEach in web-platform-tests/web-animations;
diff --git a/css-contain/contain-style-counters-ref.html b/css/css-contain/contain-style-counters-ref.html
similarity index 100%
rename from css-contain/contain-style-counters-ref.html
rename to css/css-contain/contain-style-counters-ref.html
diff --git a/css-contain/contain-style-counters.html b/css/css-contain/contain-style-counters.html
similarity index 100%
rename from css-contain/contain-style-counters.html
rename to css/css-contain/contain-style-counters.html
diff --git a/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html b/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html
new file mode 100644
index 0000000..155dbdd
--- /dev/null
+++ b/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html
@@ -0,0 +1,56 @@
+<script>
+function with_iframe(url) {
+  return new Promise(function(resolve) {
+      var frame = document.createElement('iframe');
+      frame.src = url;
+      frame.onload = function() { resolve(frame); };
+      document.body.appendChild(frame);
+    });
+}
+
+function with_sandboxed_iframe(url, sandbox) {
+  return new Promise(function(resolve) {
+      var frame = document.createElement('iframe');
+      frame.sandbox = sandbox;
+      frame.src = url;
+      frame.onload = function() { resolve(frame); };
+      document.body.appendChild(frame);
+    });
+}
+
+function fetch_in_worker() {
+  return new Promise((resolve) => {
+    var blob = new Blob([
+      "fetch('" + location.href + "_workerfetch', {mode: 'no-cors'})" +
+      "  .then(() => { self.postMessage('OK'); });"]);
+    var url = URL.createObjectURL(blob);
+    var worker = new Worker(url);
+    worker.onmessage = resolve;
+  });
+}
+
+window.onmessage = function (e) {
+  var id = e.data['id'];
+  fetch(location.href + "_fetch", {mode: 'no-cors'})
+    .then(function() {
+        return fetch_in_worker();
+      })
+    .then(function() {
+        return with_iframe(location.href + "_iframe");
+      })
+    .then(function() {
+        return with_sandboxed_iframe(location.href + "_script",
+                                     "allow-scripts");
+      })
+    .then(function() {
+        return with_sandboxed_iframe(location.href + "_script-origin",
+                                     "allow-scripts allow-same-origin");
+      })
+    .then(function() {
+        window.top.postMessage({id: id, result: 'done'}, '*');
+      })
+    .catch(function(e) {
+        window.top.postMessage({id: id, result: 'error: ' + e.toString()}, '*');
+      });
+};
+</script>
diff --git a/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js b/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js
new file mode 100644
index 0000000..ffa0aba
--- /dev/null
+++ b/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js
@@ -0,0 +1,19 @@
+var requests = [];
+
+self.addEventListener('message', function(event) {
+    event.waitUntil(self.clients.matchAll()
+      .then(function(clients) {
+          var client_urls = [];
+          for(var client of clients){
+            client_urls.push(client.url);
+          }
+          client_urls = client_urls.sort();
+          event.data.port.postMessage(
+              {clients: client_urls, requests: requests});
+        }));
+  });
+
+self.addEventListener('fetch', function(event) {
+    requests.push(event.request.url);
+    event.respondWith(fetch(event.request));
+  });
diff --git a/service-workers/service-worker/resources/test-helpers.sub.js b/service-workers/service-worker/resources/test-helpers.sub.js
index 1df4363..1f6bbaa 100644
--- a/service-workers/service-worker/resources/test-helpers.sub.js
+++ b/service-workers/service-worker/resources/test-helpers.sub.js
@@ -255,3 +255,13 @@
       })
     .then(() => navigator.serviceWorker.getRegistration(scope));
 }
+
+function with_sandboxed_iframe(url, sandbox) {
+  return new Promise(function(resolve) {
+      var frame = document.createElement('iframe');
+      frame.sandbox = sandbox;
+      frame.src = url;
+      frame.onload = function() { resolve(frame); };
+      document.body.appendChild(frame);
+    });
+}
diff --git a/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html b/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html
new file mode 100644
index 0000000..8b361bd
--- /dev/null
+++ b/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html>
+<title>ServiceWorker FetchEvent for sandboxed iframe.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+var lastCallbackId = 0;
+var callbacks = {};
+function postMessageAndWaitResult(frame) {
+  return new Promise(function(resolve) {
+    var id = ++lastCallbackId;
+    callbacks[id] = resolve;
+    frame.contentWindow.postMessage({id:id}, '*');
+  });
+}
+
+window.onmessage = function (e) {
+  message = e.data;
+  var id = message['id'];
+  var calback = callbacks[id];
+  delete callbacks[id];
+  calback(message['result']);
+};
+
+promise_test(function(t) {
+    var SCOPE = 'resources/sandboxed-iframe-fetch-event-iframe.html';
+    var SCRIPT = 'resources/sandboxed-iframe-fetch-event-worker.js';
+    var frames = [];
+    var worker;
+    return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+      .then(function(registration) {
+          worker = registration.installing;
+          return wait_for_state(t, registration.installing, 'activated');
+        })
+      .then(function() {
+          return with_iframe(SCOPE + '?iframe');
+        })
+      .then(function(frame) {
+          frames.push(frame);
+          return postMessageAndWaitResult(frame);
+        })
+      .then(function(result) {
+          assert_equals(result, 'done');
+          return with_sandboxed_iframe(SCOPE + '?script', 'allow-scripts');
+        })
+      .then(function(frame) {
+          frames.push(frame);
+          return postMessageAndWaitResult(frame);
+        })
+      .then(function(result) {
+          assert_equals(result, 'done');
+          return with_sandboxed_iframe(SCOPE + '?script-origin',
+                                       'allow-scripts allow-same-origin');
+        })
+      .then(function(frame) {
+          frames.push(frame);
+          return postMessageAndWaitResult(frame);
+        })
+      .then(function(result) {
+          assert_equals(result, 'done');
+          return new Promise(function(resolve) {
+              var channel = new MessageChannel();
+              channel.port1.onmessage = function(msg) {
+                  resolve(msg);
+                };
+              worker.postMessage({port: channel.port2}, [channel.port2]);
+            });
+        })
+      .then(function(msg) {
+          for (var frame of frames) {
+            frame.remove();
+          }
+          var expected_base_url = new URL(SCOPE, location.href).href;
+          var request_set = {};
+          for (var request of msg.data.requests) {
+            request_set[request] = true;
+          }
+          assert_true(
+              expected_base_url + '?iframe' in request_set,
+              'The request for normal iframe should be handled by SW.');
+          assert_true(
+              expected_base_url + '?iframe_fetch' in request_set,
+              'The fetch request from normal iframe should be handled by SW.');
+          assert_true(
+              expected_base_url + '?iframe_workerfetch' in request_set,
+              'The fetch request from worker in normal iframe should be ' +
+              'handled by SW.');
+          assert_true(
+              expected_base_url + '?iframe_iframe' in request_set,
+              'The request for normal iframe inside normal iframe should be ' +
+              'handled by SW.');
+          assert_false(
+              expected_base_url + '?iframe_script' in request_set,
+              'The request for sandboxed iframe with allow-scripts flag ' +
+              'inside normal iframe should not be handled by SW.');
+          assert_true(
+              expected_base_url + '?iframe_script-origin' in request_set,
+              'The request for sandboxed iframe with allow-scripts and ' +
+              'allow-same-origin flag inside normal iframe should be handled ' +
+              'by SW.');
+          assert_false(
+              expected_base_url + '?script' in request_set,
+              'The request for sandboxed iframe with allow-scripts flag ' +
+              'should not be handled by SW.');
+          assert_false(
+              expected_base_url + '?script_fetch' in request_set,
+              'The fetch request from sandboxed iframe with allow-scripts ' +
+              'flag should not be handled by SW.');
+          assert_false(
+              expected_base_url + '?script_workerfetch' in request_set,
+              'The fetch request from worker from sandboxed iframe with ' +
+              'allow-scripts flag should not be handled by SW.');
+          assert_false(
+              expected_base_url + '?script_iframe' in request_set,
+              'The request for normal iframe inside sandboxed iframe with ' +
+              'allow-scripts flag should not be handled by SW.');
+          assert_false(
+              expected_base_url + '?script_script' in request_set,
+              'The request for sandboxed iframe with allow-scripts flag ' +
+              'inside sandboxed iframe with allow-scripts flag should not be ' +
+              'handled by SW.');
+          assert_false(
+              expected_base_url + '?script_script-origin' in request_set,
+              'The request for sandboxed iframe with allow-scripts and ' +
+              'allow-same-origin flag inside sandboxed iframe with ' +
+              'allow-scripts flag should not be handled by SW.');
+          assert_true(
+              expected_base_url + '?script-origin' in request_set,
+              'The request for sandboxed iframe with allow-scripts and ' +
+              'allow-same-origin flag should be handled by SW.');
+          assert_true(
+              expected_base_url + '?script-origin_fetch' in request_set,
+              'The fetch request from sandboxed iframe with allow-scripts ' +
+              'and allow-same-origin flag should be handled by SW.');
+          assert_true(
+              expected_base_url + '?script-origin_workerfetch' in request_set,
+              'The fetch request from worker in sandboxed iframe with ' +
+              'allow-scripts and allow-same-origin flag should be handled ' +
+              'by SW.');
+          assert_true(
+              expected_base_url + '?script-origin_iframe' in request_set,
+              'The request for normal iframe inside sandboxed iframe with ' +
+              'allow-scripts and allow-same-origin flag should be handled by' +
+              'SW.');
+          assert_false(
+              expected_base_url + '?script-origin_script' in request_set,
+              'The request for sandboxed iframe with allow-scripts flag ' +
+              'inside sandboxed iframe with allow-scripts and ' +
+              'allow-same-origin flag should be handled by SW.');
+          assert_true(
+              expected_base_url + '?script-origin_script-origin' in request_set,
+              'The request for sandboxed iframe with allow-scripts and' +
+              'allow-same-origin flag inside sandboxed iframe with ' +
+              'allow-scripts and allow-same-origin flag should be handled by' +
+              'SW.');
+
+          var client_set = {};
+          for (var client of msg.data.clients) {
+            client_set[client] = true;
+          }
+          assert_true(
+              expected_base_url + '?iframe' in client_set,
+              'The normal iframe should be controlled by SW.');
+          assert_true(
+              expected_base_url + '?iframe_iframe' in client_set,
+              'The normal iframe inside normal iframe should be controlled ' +
+              'by SW.');
+          assert_false(
+              expected_base_url + '?iframe_script' in client_set,
+              'The sandboxed iframe with allow-scripts flag inside normal ' +
+              'iframe should not be controlled by SW.');
+          assert_true(
+              expected_base_url + '?iframe_script-origin' in client_set,
+              'The sandboxed iframe with allow-scripts and allow-same-origin' +
+              'flag inside normal iframe should be controlled by SW.');
+          assert_false(
+              expected_base_url + '?script' in client_set,
+              'The sandboxed iframe with allow-scripts flag should not be ' +
+              'controlled by SW.');
+          assert_false(
+              expected_base_url + '?script_iframe' in client_set,
+              'The normal iframe inside sandboxed iframe with allow-scripts' +
+              'flag should not be controlled by SW.');
+          assert_false(
+              expected_base_url + '?script_script' in client_set,
+              'The sandboxed iframe with allow-scripts flag inside sandboxed ' +
+              'iframe with allow-scripts flag should not be controlled by SW.');
+          assert_false(
+              expected_base_url + '?script_script-origin' in client_set,
+              'The sandboxed iframe with allow-scripts and allow-same-origin ' +
+              'flag inside sandboxed iframe with allow-scripts flag should ' +
+              'not be controlled by SW.');
+          assert_true(
+              expected_base_url + '?script-origin' in client_set,
+              'The sandboxed iframe with allow-scripts and allow-same-origin ' +
+              'flag should be controlled by SW.');
+          assert_true(
+              expected_base_url + '?script-origin_iframe' in client_set,
+              'The normal iframe inside sandboxed iframe with allow-scripts ' +
+              'and allow-same-origin flag should be controlled by SW.');
+          assert_false(
+              expected_base_url + '?script-origin_script' in client_set,
+              'The sandboxed iframe with allow-scripts flag inside sandboxed ' +
+              'iframe with allow-scripts and allow-same-origin flag should ' +
+              'be controlled by SW.');
+          assert_true(
+              expected_base_url + '?script-origin_script-origin' in client_set,
+              'The sandboxed iframe with allow-scripts and allow-same-origin ' +
+              'flag inside sandboxed iframe with allow-scripts and ' +
+              'allow-same-origin flag should be controlled by SW.');
+          return service_worker_unregister_and_done(t, SCOPE);
+        });
+  }, 'ServiceWorker FetchEvent for sandboxed iframe.');
+</script>
+</body>
diff --git a/webrtc/RTCCertificate.html b/webrtc/RTCCertificate.html
index f5eccab..e5f1749 100644
--- a/webrtc/RTCCertificate.html
+++ b/webrtc/RTCCertificate.html
@@ -172,8 +172,9 @@
         assert_equals(typeof fingerprint, 'object',
           'Expect fingerprint to be an object (dictionary)');
 
-        // Can only do simple test as the allowed values may be extended
-        assert_true(/^[a-zA-Z\-]+$/.test(fingerprint.algorithm),
+        // https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xml
+        const algorithms = ['md2', 'md5', 'sha-1', 'sha-224', 'sha-256', 'sha-384', 'sha-512'];
+        assert_in_array(fingerprint.algorithm, algorithms,
           'Expect fingerprint.algorithm to be string of algorithm identifier');
 
         assert_true(/^([0-9a-f]{2}\:)+[0-9a-f]{2}$/.test(fingerprint.value),