Use the crossorigin attribute of the main script on deferred hunks.

If the main script is loaded using a CORS request the deferred hunks
will be as well preventing errors from being muted.

Bug: 35594
Change-Id: I3283307b5d9e1d6708a4808e1e3fd7689a672a9b
Reviewed-on: https://dart-review.googlesource.com/c/89141
Commit-Queue: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index f0f0153..f36ace5 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -3356,6 +3356,15 @@
   return JS('String', 'String(#.nonce)', currentScript);
 }
 
+/// The 'crossOrigin' value on the current script used for CORS, if any.
+String _crossOrigin = _computeCrossOrigin();
+
+String _computeCrossOrigin() {
+  var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
+  if (currentScript == null) return null;
+  return JS('String|Null', '#.crossOrigin', currentScript);
+}
+
 /// Returns true if we are currently in a worker context.
 bool _isWorker() {
   requiresPreamble();
@@ -3501,6 +3510,9 @@
     if (_cspNonce != null && _cspNonce != '') {
       JS('', '#.nonce = #', script, _cspNonce);
     }
+    if (_crossOrigin != null && _crossOrigin != '') {
+      JS('', '#.crossOrigin = #', script, _crossOrigin);
+    }
     JS('', '#.addEventListener("load", #, false)', script, jsSuccess);
     JS('', '#.addEventListener("error", #, false)', script, jsFailure);
     JS('', 'document.body.appendChild(#)', script);
diff --git a/tests/compiler/dart2js_extra/deferred_with_cross_origin_lib.dart b/tests/compiler/dart2js_extra/deferred_with_cross_origin_lib.dart
new file mode 100644
index 0000000..48fbce6
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_with_cross_origin_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo() {
+  return "loaded";
+}
diff --git a/tests/compiler/dart2js_extra/deferred_with_cross_origin_test.dart b/tests/compiler/dart2js_extra/deferred_with_cross_origin_test.dart
new file mode 100644
index 0000000..51c10cf
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_with_cross_origin_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that code loaded via deferred imports uses the same crossorigin value as
+// the main page.
+
+import "deferred_with_cross_origin_lib.dart" deferred as lib;
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "dart:html";
+
+main() {
+  asyncStart();
+
+  var scripts = document
+      .querySelectorAll<ScriptElement>('script')
+      .where((s) => s.src.contains("generated_compilations"))
+      .toList();
+  Expect.equals(1, scripts.length);
+  Expect.equals(null, scripts.first.crossOrigin);
+  scripts.first.crossOrigin = "anonymous";
+
+  lib.loadLibrary().then((_) {
+    print(lib.foo());
+    var scripts = document
+        .querySelectorAll<ScriptElement>('script')
+        .where((s) => s.src.contains("generated_compilations"))
+        .toList();
+    Expect.equals(2, scripts.length);
+    for (var script in scripts) {
+      Expect.equals("anonymous", script.crossOrigin);
+    }
+    asyncEnd();
+  });
+}